Given a java.io.File in Kotlin, how do you get the file's extension and its name without the extension? Name the kotlin.io extension properties and explain what they return for tricky names like "archive.tar.gz" and a dotfile like ".gitignore".
answer
- extension = after last dot; "" if none
- nameWithoutExtension = before last dot
- Splits on LAST dot only (tar.gz -> gz)
- .gitignore -> extension "gitignore", name ""
- Pure string ops, no disk, no lowercasing
basics
~10 sUse the file's extension property to get the part after the last dot, and nameWithoutExtension to get the name with that part removed. They are Kotlin helpers added on top of java.io.File.
solid answer
~30 skotlin.io adds extension properties on java.io.File: File.extension returns the substring after the last '.' in the file name (empty string if there is no dot), and File.nameWithoutExtension returns name with everything from the last '.' removed. They operate on name only, not the path. For "archive.tar.gz", extension is "gz" and nameWithoutExtension is "archive.tar" — they only split on the LAST dot. For a dotfile ".gitignore", the leading dot is treated as the separator, so extension is "gitignore" and nameWithoutExtension is "". These are pure string operations: they don't touch the filesystem and don't lowercase, so comparisons should normalize case yourself.
code
kotlin · 9 linesimport java.io.File
val f = File("/data/archive.tar.gz")
println(f.name) // archive.tar.gz
println(f.extension) // gz
println(f.nameWithoutExtension) // archive.tar
// Robust extension check:
fun isImage(file: File) = file.extension.lowercase() in setOf("png", "jpg", "jpeg")go deeper
Knows extension and nameWithoutExtension exist and what each returns for a simple name.
Handles edge cases: empty string for no dot, last-dot-only on tar.gz, dotfiles, case normalization.
Notes they are pure string extension properties on java.io.File, never null, no I/O; picks them over manual substring parsing.
Frames when name-based parsing is insufficient (content sniffing / MIME detection) and why stdlib stays deliberately simple and filesystem-free.
## What these are Kotlin's standard library (`kotlin.io`) decorates `java.io.File` with **extension properties** — functions written `val File.x` that Kotlin lets you call as if they were members. Two of them parse the file *name*: - **`File.extension`** — the part of the name *after the last dot*. - **`File.nameWithoutExtension`** — the name with everything *from the last dot onward* removed. They operate purely on `File.name` (the last path segment) as a **string**. They never touch the disk, never read the file, and never lowercase anything. ## The exact rules Given the file name string: - `extension` = substring **after** the last `'.'`. If there is **no dot**, it returns the **empty string** `""` (not null). - `nameWithoutExtension` = substring **before** the last `'.'`. If there is no dot, it returns the whole name. Because the split is on the **last** dot only: ```kotlin import java.io.File File("archive.tar.gz").extension // "gz" File("archive.tar.gz").nameWithoutExtension // "archive.tar" File("README").extension // "" (no dot) File("README").nameWithoutExtension // "README" File(".gitignore").extension // "gitignore" (leading dot = separator) File(".gitignore").nameWithoutExtension // "" File("/a/b/data.csv").extension // "csv" (path is ignored, only name) ``` ## Gotchas - **No null.** A file with no extension yields `""`, so `if (file.extension == "")` not `== null`. - **Dotfiles** like `.env` / `.gitignore` count the leading dot as the separator, giving a surprising extension and an empty `nameWithoutExtension`. - **Multi-part extensions** (`.tar.gz`) only lose the last segment. - **Case sensitivity** — `"IMG.PNG".extension` is `"PNG"`; normalize with `.lowercase()` before comparing. - These are **String parsers**, so they work even if the file doesn't exist on disk. Related helpers in the same family: `File.name` (last segment with extension) and `File.path`/`File.absolutePath`.
- What does File("noext").extension return — null or empty string?Empty string "". These properties never return null; check with isEmpty() or == "".
- Do extension and nameWithoutExtension look at the whole path?No, only File.name (the last segment). The directory portion is ignored.
Like splitting a person's email at the last '@' or a filename at its trailing tag — only the final marker counts.
saying these in an interview costs you the question
- Saying extension returns null when there is no dot
- Claiming "archive.tar.gz".extension is "tar.gz"
- Thinking these read the file from disk
- Assuming the result is lowercased automatically
- Confusing File.name with File.nameWithoutExtension