何をしたいユーティリティか:「ファイル名取得」
ここで作りたいのは、URL やパス文字列から「ファイル名だけ」を取り出す小さな関数です。
例えば、こういうイメージです。
https://example.com/assets/logo.png → "logo.png"/downloads/archive.zip → "archive.zip"/path/to/dir/ → ""(ファイル名なしとみなす)/path/to/file → "file"
「拡張子取得」と違って、ここでは「最後のパス要素そのもの」が欲しい、というユーティリティです。
ダウンロード時のデフォルトファイル名に使ったり、ログ表示に使ったり、地味だけどよく出てきます。
ファイル名取得の基本的な考え方
どこからどこまでを「ファイル名」とみなすか
ファイル名取得でやりたいことは、ざっくり言うとこうです。
- URL からクエリ(
?以降)やハッシュ(#以降)を取り除く。 - 残ったパスのうち、「最後の
/以降」をファイル名とみなす。 - その部分が空なら「ファイル名なし」と判断する。
例えば、https://example.com/assets/logo.png?version=1#top なら、
URL 全体 → https://example.com/assets/logo.png?version=1#top
クエリ・ハッシュ除去 → https://example.com/assets/logo.png
最後の / 以降 → logo.png
という流れです。
一番シンプルな「ファイル名取得」関数
URL 文字列からファイル名を取る getFileName
まずは、クエリやハッシュを無視して、「パス部分だけからファイル名を取る」関数を作ります。
function getFileName(url) {
if (!url) return "";
const str = String(url);
const pathWithoutQuery = str.split(/[?#]/)[0];
const lastSlashIndex = pathWithoutQuery.lastIndexOf("/");
const filename =
lastSlashIndex >= 0
? pathWithoutQuery.slice(lastSlashIndex + 1)
: pathWithoutQuery;
if (!filename) {
return "";
}
return filename;
}
JavaScript重要なポイントをかみ砕いて説明する
ここがこのユーティリティの核なので、順番に見ていきます。
クエリとハッシュを先に落とす
const pathWithoutQuery = str.split(/[?#]/)[0];
JavaScriptURL には、? 以降のクエリや # 以降のハッシュが付いていることがよくあります。
/assets/logo.png?version=1#top のようなケースです。
ファイル名を取りたいのは「パス部分」だけなので、? または # で分割して、一番前の部分だけを使います。
結果として、/assets/logo.png だけが残ります。
最後の / 以降を「ファイル名」とみなす
const lastSlashIndex = pathWithoutQuery.lastIndexOf("/");
const filename =
lastSlashIndex >= 0
? pathWithoutQuery.slice(lastSlashIndex + 1)
: pathWithoutQuery;
JavaScriptlastIndexOf("/") は「一番後ろの / の位置」を返します。
/assets/logo.png の場合、/assets/ と logo.png の境目の / の位置が返ってきます。
そこから +1 した位置から最後までを slice すると、logo.png になります。
もし / が含まれていない場合(単なる "logo.png" や "file" など)は、
全体をそのままファイル名とみなします。
ファイル名が空なら「なし」とみなす
if (!filename) {
return "";
}
JavaScript/path/to/dir/ のように、最後が / で終わっている場合を考えます。
"/path/to/dir/".lastIndexOf("/") は末尾の / の位置になります。
そこから +1 して slice すると、空文字列になります。
この場合は「ファイル名ではなくディレクトリ」とみなして、空文字を返すようにしています。
実際の動きを例で確認する
典型的な URL の例
getFileName("https://example.com/assets/logo.png");
// "logo.png"
getFileName("/downloads/archive.zip");
// "archive.zip"
getFileName("/path/to/file");
// "file"
JavaScript最後のパス要素が、そのままファイル名として取れているのが分かると思います。
クエリやハッシュ付きの例
getFileName("/assets/logo.png?version=1");
// "logo.png"
getFileName("/assets/logo.png#top");
// "logo.png"
getFileName("/assets/logo.png?version=1#top");
// "logo.png"
JavaScriptクエリやハッシュは先に切り落としているので、
ファイル名取得には影響しません。
ディレクトリっぽいパスの例
getFileName("/path/to/dir/");
// ""(ファイル名なし)
getFileName("/path/to/dir");
// "dir"(最後の要素をファイル名とみなす)
JavaScriptここは設計の好みが分かれるところですが、
「末尾が / で終わっているものはディレクトリ扱い」として、
ファイル名なし(空文字)を返すようにしています。
拡張子取得と組み合わせる
ファイル名と拡張子を両方使いたい場合
前に作った getExtension と組み合わせると、
「ファイル名」と「拡張子」を両方扱えるようになります。
例えば、こんなユーティリティが書けます。
function getFileNameWithoutExtension(url) {
const filename = getFileName(url);
if (!filename) return "";
const lastDotIndex = filename.lastIndexOf(".");
if (lastDotIndex <= 0) {
return filename;
}
return filename.slice(0, lastDotIndex);
}
JavaScript動きはこうです。
getFileNameWithoutExtension("https://example.com/assets/logo.png");
// "logo"
getFileNameWithoutExtension("/downloads/archive.tar.gz");
// "archive.tar"
getFileNameWithoutExtension("/path/to/file");
// "file"
getFileNameWithoutExtension("/path/to/dir/");
// ""
JavaScriptgetFileName で「最後の要素」を取り、
そこからさらに「最後のドットより前」を取り出す、という二段構えです。
実務での使いどころと設計のポイント
ダウンロード時のデフォルト名に使う
例えば、API から返ってきた URL をそのままダウンロードリンクに使うとき、
「保存ダイアログに出すデフォルト名」を決めたいことがあります。
const url = "https://example.com/files/report_2025-01-01.xlsx";
const filename = getFileName(url) || "download.dat";
JavaScriptこうしておけば、URL にファイル名が含まれていればそれを使い、
なければフォールバックの名前を使う、という挙動にできます。
ログや UI 表示で「最後の要素だけ見せたい」場合
長いパス全体ではなく、「最後のファイル名だけ」を表示したい場面も多いです。
const url = "/uploads/user/12345/avatar.png";
console.log("アップロードされたファイル:", getFileName(url));
// "アップロードされたファイル: avatar.png"
JavaScriptユーザーに見せるときも、/uploads/user/12345/avatar.png より avatar.png の方が親切なことが多いです。
「パスの構造」と「ファイル名」を分けて考える
URL を扱うときは、
パス全体(どこにあるか)
ファイル名(何という名前か)
拡張子(どんな種類か)
を分けて考えると、設計がきれいになります。
今回の getFileName は、そのうち「ファイル名」の部分だけを取り出す役割です。joinPath や getExtension と組み合わせると、URL 周りの処理がかなり整理されます。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
getFileName("https://example.com/assets/logo.png");
getFileName("/downloads/archive.zip?version=3");
getFileName("/path/to/file");
getFileName("/path/to/dir/");
getFileName("file-only.txt");
JavaScript「どの部分がファイル名として取れて、どのケースで空文字になるか」を、
自分の目で確認してみてください。
そのうえで、自分のプロジェクトに
export function getFileName(url) { ... }
export function getFileNameWithoutExtension(url) { ... }
JavaScriptを置いて、
ファイル名が欲しくなったら、
毎回 split("/") ではなく、必ず getFileName を通す、というルールにしてみてください。
それだけで、あなたの「ファイル名扱い」は、
場当たり的な文字列操作から、意図がはっきりした“業務レベルのファイル名取得ユーティリティ”に一段レベルアップします。

