2

ディレクトリの内容を一覧表示し、特定のファイルの名前を変更しようとしています。

public void run(String dirName) {
    try {
        File parDir = new File(dirName);
        File[] dirContents = parDir.listFiles();

        // Rename if necessary
        for(File f : dirContents) {
            System.out.println("f is:\n" + f.toString());
            String name = f.getName();
            String subbedName = name.replaceAll("\uFFFD", "_");

            System.out.println("\n" + "name = " + name + ", subbedName = " + subbedName + "\n");

            if(!name.equals(subbedName)) {
                File newFile = new File(f.getParentFile(), subbedName);
                System.out.println("newFile is:\n" + newFile.toString());
                if(!f.renameTo(newFile))
                    System.out.println("Tried to change file name but couldn't.");
            }
        }
    }
    catch(Exception exc1) {
        System.out.println("Something happened while listing and renaming directory contents: " + exc1.getMessage());
    }
}

これを実行すると、「 Javaがこれらのファイルを「開いている」と見なしているとは思わTried to change file name but couldn't.ないので、それが理由ではないと思います。メソッドに渡された文字列の値がどこにあるかを実行したこともあります。chmod 777 myDirmyDirdirNamerun

ここで何が欠けていますか?Javaがこれらのファイルの名前を変更しないのはなぜですか?これらはCentOSマシンです。

編集f:との両方のプリントアウトを追加しましnewFileた。これは次のとおりです。

f is:
/root/path/to/mydir/test�.txt

newFile is:
/root/path/to/mydir/test_.txt
4

3 に答える 3

2

これらのファイルのフルパス名を使用して、新しいFileオブジェクトを作成する必要があります。そう

String name = f.getName(); // gets the name without the directory

おそらく次のようになります。

String name = f.getAbsolutePath();

(検索/置換を変更する必要がある場合があります)

于 2012-08-24T13:30:05.683 に答える
2

問題は、f.getName()で表されるパスの姓コンポーネントを返すことですf。次に、この文字列をマッサージして、元に戻しFileます。ただし、File現在のパスは、元のパスを含むディレクトリではなく、現在のディレクトリからの相対パスを表します。

その結果、コードは実際にファイルの名前をdirNameアプリケーションの現在のディレクトリから変更しようとしています。dirNameこれらの名前のファイルが現在のディレクトリに既に存在するか、と現在のディレクトリが異なるファイル システムにあるために失敗する可能性があります。(あるファイルシステムから別のファイルシステムにファイルの名前を変更することはできません...コピーする必要があります。)

FileJava の a は、ファイルやフォルダーではなく、パス名を表すことに注意してください。コードでは、fオブジェクトは String で示されるディレクトリ内のファイル システム オブジェクト (ファイルまたはフォルダー) のパス名ですdirname。これらの各fオブジェクトはディレクトリ部分があります。


コードを修正する方法は複数あります。例えば

  • name = f.getName()に変更name = f.toString()
  • new File(subbedName)に変更new File(f.getParentFile(), subbedName)

私は別の/追加の理論を持っています。

文字を含むファイルのパス名は\uFFFD「mojibake」として出てきます。つまり、間違ったエンコーディングを使用してエンコードされたテキストを表示すると、文字化けしたテキストが表示されます。また、3 文字の文字化けしたテキストが表示されているため、UTF-8 レンダリングを\uFFFDLatin-1 として表示しようとしていると思われます。

したがって、私の理論では、メソッドがシステムコールに提供するフォームにFile.renameTo変換するときに、同じ考えが起こっているということです。f何らかの理由でJavaが間違ったエンコーディングを使用している可能性があり、その結果、ファイルシステム内のファイルの名前と一致しない元のファイルの「名前」が生成されます。これは、名前変更が失敗するのに十分です。

おそらく関連する質問/リンク:

于 2012-08-24T13:30:42.950 に答える
1

f.getName();フルパスではなく、フォルダーの名前のみを返します。なのでsubbedName相対パスファイルになります。f.getCanonicalPath()代わりに何かを試してください。

于 2012-08-24T13:31:18.270 に答える