3

描述

我的目标是将所有文件路径存储在一个文件中。为此,我构建了一个浏览特定文件夹的递归方法。但是,结果仍然是空的...

代码

public void main(String[] args) {
    String files = browseFolder("", new File("blablalbla/.../toto"));

    FileWriter writer = new FileWriter(new File("result/"));
    writer.write(files);
    writer.close();
}

private static String browseFolder(String result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result += fileEntry.getPath() + "\n";
        }
    }
    return result;
}

由于sysout. 但是,我的结果文件是空的。

任何想法 ?谢谢你。

4

3 回答 3

3

由于String(变量result总是在内存中引用相同的字符串值)的不变性,您应该使用 concat 来保存结果,因为它实际上创建了对新字符串值的新引用。

if (fileEntry.isDirectory()) {
    result += browseFolder(result, fileEntry);
}
于 2020-01-20T09:46:18.417 回答
2

browseFolder(result, fileEntry);

您忽略了String递归方法返回的值,这就是为什么String最后得到一个空的原因。

我建议您将 a 传递给递归方法,而不是连接Strings,这会导致String创建许多实例。StringBuilder

这样,您的方法可以修改StringBuilder, 而不必返回值。

public void main(String[] args) {
    StringBuilder files = new StringBuilder();
    browseFolder(files, new File("blablalbla/.../toto"));

    FileWriter writer = new FileWriter(new File("result/"));
    writer.write(files.toString());
    writer.close();
}

private static void browseFolder(StringBuilder result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        } else {
            System.out.println(fileEntry.getPath());
            result.append(fileEntry.getPath()).append("\n");
        }
    }
}
于 2020-01-20T09:52:47.407 回答
2

请注意,递归调用browseFolder不会更改其参数,因为String它是不可变的。传递给方法的字符串变量在该方法返回后将始终保持不变。这意味着只要blablalbla/.../toto目录中充满了子目录,您的 main 调用browseFolder将返回一个空字符串,因为您没有对result.

可以browseFolder将递归调用的返回值附加到result,如下所示:

private static String browseFolder(String result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            // here:
            result += browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result += fileEntry.getPath() + "\n";
        }
    }
    return result;
}

但是,每次执行此操作时都会创建一个新字符串,因此非常浪费。您可以改用 a StringBuilder(它是可变的!)。

private static StringBuilder browseFolder(StringBuilder result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result.append(fileEntry.getPath()).append("\n");
        }
    }
    return result;
}

来电者也必须改变。您可以.toString在 a 上将其StringBuilder转换为String.

String files = browseFolder(new StringBuilder(), new File("blablalbla/.../toto")).toString();
于 2020-01-20T09:53:17.117 回答