コース一覧
    Java中級:例外処理とファイル入出力
    Path でファイルパスを扱う

    Java中級:例外処理とファイル入出力

    例外処理とファイル入出力を学び、失敗に対応しながらデータを読み書きするプログラムを作れるようにします。

    1
    例外処理
    01. try-catch で例外をつかむ5分
    02. 複数の catch ブロック5分
    03. throws と例外の伝播5分
    04. 独自の例外を作る5分
    05. try-with-resources5分
    06. finally ブロック5分
    07. 例外処理 まとめクイズ5分
    2
    ファイル I/O
    01. Files でファイルに書き込む5分
    02. ファイルを行単位で読む5分
    03. Path でファイルパスを扱う5分
    04. BufferedReader と Stream API5分
    05. ファイルの存在確認と削除5分
    06. ファイル I/O まとめクイズ5分

    Path でファイルパスを扱う

    文字列でつないだら、スラッシュが 2 つになった

    保存先のディレクトリとファイル名を dir + "/" + name でつなぐ。ほとんどの場合これで動いてしまうので、たちが悪いのです。dir の末尾にすでに / が付いていれば // になり、Windows では区切りが \ なので / と混ざり、name 側に階層が含まれていれば意図しない場所を指します。どれもファイルが見つからなくなってから気づきます。

    Java にはパス専用の型があります。java.nio.file.Path です。文字列から作るには Paths.get に渡します。複数の文字列を渡せば、その環境に合った区切り文字でつないでくれます。

    Java

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Demo {
        public static void main(String[] args) {
            Path dir = Paths.get("/var/log", "app");
            Path full = dir.resolve("server.log");
    
            System.out.println(dir);    // /var/log/app
            System.out.println(full);   // /var/log/app/server.log
        }
    }

    つなぎ足すときに使うのが resolve です。dir.resolve("server.log") は、dir の下に名前を 1 つ足した新しい Path を返します。区切り文字が足りているかどうかを気にする必要はありません。Path は書き換わらない型なので、dir 自身は /var/log/app のままです。

    resolve にはひとつ癖があります。引数が絶対パスだった場合は、左側を捨てて引数をそのまま返します。

    Java

    Path dir = Paths.get("/var/log/app");
    System.out.println(dir.resolve("/etc/hosts"));   // /etc/hosts

    利用者から受け取った値をそのまま足す場面では、この動きが意図と合っているか確かめてください。

    末尾の / は、無いものとして扱われる

    組み立てた Path は、部品に分けて取り出せます。よく使うのは次の 2 つです。

    Java

    Path full = Paths.get("/var/log/app/server.log");
    
    System.out.println(full.getFileName()); // server.log
    System.out.println(full.getParent());   // /var/log/app

    getFileName はいちばん末尾の名前を、getParent はそれを除いた親側を返します。ここで気をつけたいのは、どちらの戻り値も String ではなく Path だということです。文字列として扱いたいときは toString() を呼びます。

    もうひとつの癖が、末尾の区切り文字を意味のあるものとして扱わない点です。/a/b/c/ と /a/b/c は同じパスと解釈されるので、末尾に / が付いていても getFileName が返すのは c です。ディレクトリを指す文字列とファイルを指す文字列が混ざって届く場面では、この性質に助けられます。

    解説

    Path は「どこを指すか」を表すだけで、ディスクには一切触りません。実際にそこにファイルがあるかを確かめたり、読み書きしたりするのは Files クラスの役目です。この役割分担が分かると、どちらのクラスを探せばいいかで迷わなくなります。

    やってみよう

    Solution.lastName(String pathStr) を完成させます。

    1. ファイルの先頭に import java.nio.file.Paths; を書く
    2. 受け取った文字列から Path を作る。split や lastIndexOf で自前で切り出してはいけません
    3. 末尾の名前を取り出し、String に変換して return する

    lastName("/tmp/foo/bar.txt") は "bar.txt"、lastName("simple.txt") は "simple.txt" です。lastName("/a/b/c/") が "c" になるのは、さきほどの末尾の / の扱いがそのまま効いているからです。

    要件

    1. ファイル先頭で import java.nio.file.Paths; を書くこと
    2. Paths.get(pathStr) を使って Path を生成すること (自前で String 操作しない)
    3. getFileName() で末尾を取得し、toString() で String に変換して return すること

    ヒント

    実装本体は `return Paths.get(pathStr).getFileName().toString();` の 1 行で書けます

    `getFileName()` の戻り値は `Path` 型なので、そのまま `return` するとコンパイルエラーになります。必ず `.toString()` を呼びましょう

    `/a/b/c/` のように末尾が `/` で終わっていても、`Path` 側で吸収して `c` を返してくれます。自分で末尾の `/` を取り除く処理は不要です

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

    関連レッスン

    • BufferedReader と Stream API

      BufferedReader の発想を引き継ぎつつ、Files.lines で 1 行ずつ Stream<String> としてファイルを読み込み、Stream API で集計するモダンな書き方を学ぼう。

    • ファイルの存在確認と削除

      Files.exists / Files.delete などの基本 API を使い、一時ファイルを作って存在を確認し、削除してからもう一度確認するコードを書いてみよう。

    • ファイル I/O まとめクイズ

      ファイル I/O 章 (Files / Path / BufferedReader / try-with-resources) の総まとめ。書き込み API の使い分け、リソースの自動 close、文字コード、例外処理の組み合わせを 4 択クイズで再確認する。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • ディレクトリファイルを整理するフォルダのこと。
    • 階層ネットワークを役割ごとに積み重ねた構造
    • 引数位置引数=順番で渡す。
    • 戻り値呼び出し元への返答を表す点線矢印
    • クラスデータと振る舞いを束ねる単位
    main.java
    エディタを読み込んでいます

    メモ

    Path でファイルパスを扱う

    ⌘S で保存