Java - 如何使用此程序更有效地“扫描”文件系统的一部分?

时间:2016-01-08 00:48:12

标签: java

我正在研究Java中的概念验证程序的一部分,以获得我的防病毒概念。现在我仍然只是在喋喋不休,细节并不重要,但我希望我正在编写的程序能够获得彼此特定范围内的每个文件的文件路径(比如相隔5个等级)目录并将它们写入文本文件。

我现在所拥有的(我将在下面包含我的代码)可以通过检查目录中给定文件夹中是否有文件并将文件路径写入文本文件,然后关闭来在有限的范围内执行此操作另一个级别再做一次。我把它设置为目前在目录中做2个级别,它有点工作。但它只有在目录的给定级别中只有一个项目时才有效。如果有一个文本文件,它会将该文件路径写入另一个文本文件,然后终止。但是如果有文本文件和文件夹,它会忽略文本文件并转到下一级目录并记录它在那里找到的任何文本文件的文件路径。如果有两个或更多文件夹,它将始终选择一个特别是另一个或其他文件夹。

我现在意识到它正在这样做,因为我使用了错误的条件。我使用if else并且应该做其他事情,但我不确定应该使用哪一个。但是我必须这样做,我想修复它,以便它与每个级别分支。例如,我启动程序并将其作为起始目录C:/Users/"Name"/Desktop/test/。 Test有2个文件夹和一个文本文件。按照我想要的方式工作,它会记录.txt的文件路径,在两个文件夹中记下一个级别,记录它在那里找到的任何.txts或其他文件,然后在另一个级别进入它找到的每个文件夹在这两个文件夹中,记录它在那里找到的内容,依此类推,直到完成预定数量的级别。

编辑:为了澄清对问题的疑虑,我会总结一下。我希望程序在另一个文本文件中编写它在目录的每个级别中找到的任何文件的文件路径。它会执行此操作,但仅限于给定级别的目录中有一个文件。例如,如果只有一个.txt,它会将该.txt的文件路径写入另一个文本文件。但是如果该目录级别中有多个文件(例如,两个.txts),它只会写入其中一个文件的文件路径而忽略另一个文件路径。如果有.txt和文件夹,它会忽略.txt并进入文件夹以转到下一级目录。我希望它记录给定位置的所有文件,然后分支到同一位置的所有文件夹。

编辑2:我得到了我的代码的一部分,它从这个问题(Read all files in a folder)获取文件路径,并从我的那个(How do I create a file and write to it in Java?)写入我的其他文本文件的部分

编辑3:我如何编辑我的代码以进行递归,因为@horatius指出我需要?

编辑4:如何编辑我的代码,使其不需要硬编码的起始文件路径才能工作,而是可以检测可执行文件.jar的位置并将其用作起始目录?

这是我的代码:

public class ScanFolder {

private static final int LEVELS = 5;

private static final String START_DIR = "C:/Users/Joe/Desktop/Test-Level1/";
private static final String REPORT_FILE = "C:/Users/Joe/Desktop/reports.txt";

public static void main(String[] args) throws IOException {
    try (PrintWriter writer = new PrintWriter(REPORT_FILE, "UTF-8");
            Stream<Path> pathStream = Files.walk(Paths.get(START_DIR), LEVELS)) {

         pathStream.filter(Files::isRegularFile).forEach(writer::println);

       } catch (Exception e) {
         e.printStackTrace(System.err);
       }
     }
   }

提前致谢

1 个答案:

答案 0 :(得分:1)

如果您使用Files.walk(...),它会为您完成所有递归。

打开并写入PrintWriter将在每次打开/写入时截断输出文件,只留下最后写入的文件名。

我认为下面的内容就是你所追求的。当您前进而不是写入文件时,您可能希望将找到的Path对象放入ArrayList<Path>或类似对象中以便以后处理,但不清楚您的问题,这里有什么要求。

public class Walk
{
  public static void main(String[] args) throws IOException {
    try (PrintWriter writer = new PrintWriter("C:/Users/Joe/Desktop/reports.txt", "UTF-8")) {
      Files.walk(Paths.get("C:/Users/Joe/Desktop/test")).forEach(filePath -> {
        if (Files.isRegularFile(filePath)) {
          writer.println(filePath);
        }
      });
    }
  }
}

以下是一个可用于限制深度的改进示例。它还处理正确关闭前一个示例没有的Stream返回的Files.walk(...),并且是更多的stream / lambda惯用语:

public class Walk
{
  // Can use Integer.MAX_VALUE for all
  private static final int LEVELS = 2;

  private static final String START_DIR = "C:/Users/Joe/Desktop/test";
  private static final String REPORT_FILE = "C:/Users/Joe/Desktop/reports.txt";

  public static void main(String[] args) {
    try (PrintWriter writer = new PrintWriter(REPORT_FILE, "UTF-8");
         Stream<Path> pathStream = Files.walk(Paths.get(START_DIR), LEVELS)) {

      pathStream.filter(Files::isRegularFile).forEach(writer::println);

    } catch (Exception e) {
      e.printStackTrace(System.err);
    }
  }
}