【问题标题】:Java invoke listing files from command lineJava 从命令行调用列表文件
【发布时间】:2014-11-20 08:39:11
【问题描述】:

我尝试使用 java 从命令行调用文件列表。它看起来像这样:

try {
p=Runtime.getRuntime().exec("cmd.exe /k dir /b /S /a-d \"C:\\Image");
    } catch (IOException e1) {
        e1.printStackTrace();
    } 
    BufferedReader reader=new BufferedReader(
    new InputStreamReader(p.getInputStream())
    ); 

然后我一行一行地准备好……这行得通。

但我也想获得文件名和文件大小,所以我尝试这样调用:

try {
p=Runtime.getRuntime().exec("cmd.exe for %F in (\"C:\\Image*\") do @echo %~zF  %F");
    } catch (IOException e1) {
        e1.printStackTrace();
    } 
    BufferedReader reader=new BufferedReader(
    new InputStreamReader(p.getInputStream())
    ); 

这仅返回两行: Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。版权所有。 这不是文件名和文件大小;)

这是否可以通过从 java 代码中调用 cmd 来获取这些信息(文件大小)?

【问题讨论】:

  • 是否有理由这样做,而不是使用 Java 库?您所做的将非常脆弱,并且只能在 Windows 上运行。
  • 同时调用第三方程序会使您的系统易受攻击:想象一下cmd.exe 是否是一个被屏蔽的受感染文件
  • Env 只是 windows。我需要使用命令行运行,因为在某些位置我需要列出 5k-10-15k 文件。如果我只使用 java 文件,这是一个性能杀手……我不完全确定,但使用 shell 列出应该快得多并减少 IO 到磁盘。基本上我需要知道文件三个信息:文件名、文件大小和最后修改日期。
  • @user1055201 我不明白为什么它会减少文件 I/O,但无论如何我已经发布了一个答案,解释了我认为错误在哪里,以及如何使用更现代的Files 而不是File。

标签: java file command-line


【解决方案1】:

使用File类获取文件大小和文件名:

public void listFilesForFolder(File folder) {
    for (File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForFolder(fileEntry);
        } else {
            System.out.println(fileEntry.getName());
            System.out.println(fileEntry.getTotalSpace());

        }
    }
}

【讨论】:

  • 我已经在使用 java 文件并且对于我的位置有 10k-15k 文件的性能不好,这就是为什么我想使用 Shell 命令检查它是如何工作的。
  • 您可以向用户显示进度条以了解他们的进度,但在我看来,与仅使用该语言相比,使用 shell 来获得额外的一分钟左右并不好(这是值得商榷的)
  • 我不想展示进步。用户需要尽快获取文件列表,他不能等待简单的列表 3-4 分钟。
【解决方案2】:

您的问题的答案就目前而言是您正在查看C:\Image*,我认为您的意思是查看C:\Image\*。尝试将相关位更改为

(\"C:\\Image\\*\")

(您可能需要*.*,这取决于Windows 最近是否赶上了世界其他地方。)

但你真的不应该这样做。正确的做法是:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*")) {
    for (Path entry: stream) {
        System.out.println(entry.toString()+" has size "+Files.size(entry)
             +" and date "+Files.getLastModifiedTime(entry).toString());
    }
} catch (DirectoryIteratorException ex) {
    // do some error processing
}

我看不出有任何理由认为 shell 命令会更快。它执行相同的磁盘 I/O。

【讨论】:

  • 更改为 (\"C:\\Image\*\") 没有帮助。
  • @user1055201 但请注意 *! 之前的双反斜杠!
  • 是的,我使用双“\”(在其他情况下代码无法编译)
猜你喜欢
  • 2018-07-30
  • 2013-04-28
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多