- PR -

File.listFiles で取れる File で相対パスを取りたい

1
投稿者投稿内容
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2004-01-29 21:53
まさです。

new File("<絶対パスで指定したディレクトリ>").listFiles() で取れる File オブジェクトで
指定したディレクトリからの相対的なパスを取得したいのですがどのようにすればよいでしょうか?

たとえば、下記のようなディレクトリ構成があるとします。
コード:
 C:/
 └ Temp/
    └ a/
      └ aa/
        ├ aaa
        ├ aab
        └ aac



コード:
import java.io.File;
import java.io.IOException;

public class Test {

    public static void main(String[] args) {
        File target;
        target = new File("C:/Temp/a");

        printList(target);
    }

    private static void printList(File target) {

        if (target.isDirectory()) {
            File[] fileList;
            fileList = target.listFiles();

            for (int index = 0; index < fileList.length; index++) {
                printList(fileList[index]);
            }

        } else {
            try {
                System.out.println("target = " + target);
                System.out.println("getName = " + target.getName());
                System.out.println("getPath = " + target.getPath());
                System.out.println("getAbsolutePath = " + target.getAbsolutePath());
                System.out.println("getCanonicalPath = " + target.getCanonicalPath());
                System.out.println();

            } catch (IOException ex) {
                ex.printStackTrace(System.err);
            }
        }
    }

}



結果:
-------------------------------------------------------------
target = C:/Temp/a/aa/aaa
getName = aaa
getPath = C:/Temp/a/aa/aaa
getAbsolutePath = C:/Temp/a/aa/aaa
getCanonicalPath = C:/Temp/a/aa/aaa

target = C:/Temp/a/aa/aab
getName = aab
getPath = C:/Temp/a/aa/aab
getAbsolutePath = C:/Temp/a/aa/aab
getCanonicalPath = C:/Temp/a/aa/aab

target = C:/Temp/a/aa/aac
getName = aac
getPath = C:/Temp/a/aa/aac
getAbsolutePath = C:/Temp/a/aa/aac
getCanonicalPath = C:/Temp/a/aa/aac
-------------------------------------------------------------

となる。

aaa -> ./aa/aaa
aaa -> ./aa/aab
aaa -> ./aa/aac

という相対パスを取りたい。
難しいでしょうか。。。?
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2004-01-29 23:26
非常に惜しいところまで来ています

File#listFiles() の代わりに File#list() を使ってみてはいかがでしょう。
ただし、指定したディレクトリからの相対パスは自分で組み立てる必要があります。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-01-29 23:32
まささん、こんにちは。

説明の最後のほうが理解できなかったので外してるかも
知れませんが、パス名の文字列操作で出来そうな気がします。

ターゲットのファイルの getCanonicalPath()で得られた文字列
から、指定したディレクトリのパスの文字列と一致する部分を
取り除いて、先頭に"./" を付加してはどうでしょうか?

このとき、指定したディレクトリのパス名も getCanonicalPath()
したものでないと、うまく行かない場合があると思います。
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2004-01-30 08:53
まさです。

Gioさん、Kissingerさん、こんちわ。
すいません。ちょっと勘違いしてしまいました。

引用:

aaa -> ./aa/aaa
aaa -> ./aa/aab
aaa -> ./aa/aac



と書きましたが、本当は

aaa -> a/aa/aaa
aaa -> a/aa/aab
aaa -> a/aa/aac

の相対パスがとりたいです。
これなら簡単に取れますでしょうか?

どちらにしても、Gioさん・Kissingerさんが言うように
文字列操作になってしまいますかねぇ。。。

とりあえず、list 試してみます。

[ メッセージ編集済み 編集者: まさ 編集日時 2004-01-30 08:54 ]
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2004-01-30 12:41
まさです。
list を使って下記のように修正してみました。

コード:
import java.io.File;

public class Test {

    public static void main(String[] args) {
        File target;
        target = new File("C:/Temp/a");

        String baseName;
        baseName = target.getName();

        printList(target, baseName);
    }

    private static void printList(File target, String filePath) {

        if (target.isDirectory()) {
            String[] fileList;
            fileList = target.list();

            for (int index = 0; index < fileList.length; index++) {
                File childFile;
                childFile = new File(target, fileList[index]);

                String nextPath;
                nextPath = filePath
                        + System.getProperty("file.separator")
                        + childFile.getName();

                printList(childFile, nextPath);
            }

        } else {
            System.out.println(filePath);
        }
    }

}



処理結果:
a/aa/aaa
a/aa/aab
a/aa/aac

となり、思い通りの結果が取れました。
ご協力ありがとうございました。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2004-01-30 16:36
おめでとうございます

一つ処理効率の点で指摘させていただくと、再帰するメソッドのしかもループの中で、常に同じ値しか返さない System.getProperty("file.separator") を繰り返し呼び出しているのが気になります。

File#separatorChar フィールドが System.getProperty("file.separator") の値で初期化されているので、これを使うと幾分か速度が上がると思います。

以上、老婆心でした
1

スキルアップ/キャリアアップ(JOB@IT)