【问题标题】:How to get short-filenames in Windows using Java?如何使用 Java 在 Windows 中获取短文件名?
【发布时间】:2013-09-19 11:23:17
【问题描述】:

如何在 Windows 中使用 Java 获取长文件名的短文件名?

我需要使用 Java(tm) 确定存储在 Windows 系统上的文件的短文件名。

【问题讨论】:

标签: java windows short-filenames


【解决方案1】:

自我回答

有相关问题和相关答案。然而,我发布了这个解决方案,因为它使用 Java(tm) 代码而不需要外部库。欢迎针对不同版本的 Java 和/或 Microsoft(R) Windows(tm) 提供其他解决方案。

主要概念

主要概念在于通过运行时类从Java(tm)调用CMD:

cmd /c for %I in ("[long file name]") do @echo %~fsI

解决方案

在 Windows 7 系统上运行的 Java SE 7 上测试 (为简洁起见,代码已减少)。

    public static String getMSDOSName(String fileName)
    throws IOException, InterruptedException {

    String path = getAbsolutePath(fileName);

    // changed "+ fileName.toUpperCase() +" to "path"
    Process process =
        Runtime.getRuntime().exec(
            "cmd /c for %I in (\"" + path + "\") do @echo %~fsI");

    process.waitFor();

    byte[] data = new byte[65536];
    int size = process.getInputStream().read(data);

    if (size <= 0)
        return null;

    return new String(data, 0, size).replaceAll("\\r\\n", "");
}

public static String getAbsolutePath(String fileName)
    throws IOException {
    File file = new File(fileName);
    String path = file.getAbsolutePath();

    if (file.exists() == false)
        file = new File(path);

    path = file.getCanonicalPath();

    if (file.isDirectory() && (path.endsWith(File.separator) == false))
        path += File.separator;

    return path;
}

【讨论】:

  • 解决方案很好但是有一个小bug。 fileName.toUpperCase() 应该删除 toUpperCase,因为该转换可能会进行一些与 windows 字符集的工作方式不兼容的转换。作为回报,windows 可能找不到该文件。我的文件名错误,如“20140506_224702_Bäckerstraße.jpg”,通过转换变成“20140506_224702_BÄCKERSTRASSE.JPG”。
【解决方案2】:

我发现了一个小问题 Osmund 的解决方案。由于某种原因,此文件名无法正常工作:

N:\directoryY\tmp\temp\asdfasdf sdf dsfasdf [dfadss]\[asdfas] asdfasd asd asdfasdf ~fdfsdfdfdsfdfdfdfdfd~ TTTm7-9  [RR 1234a5678 A.888 OKOK]a

我不确定到底是为什么。但是,如果您以稍微不同的方式运行命令(使用 ProcessBuilder),它就可以工作。这是新代码(我使用 BufferedReader 读取输出,它更干净)。

    public static String getMSDOSName(String path) throws IOException, InterruptedException {
        Process process = new ProcessBuilder().command("cmd", "/c", "for %I in (\"" + path + "\") do @echo %~fsI").start();
        process.waitFor();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            return br.readLine();
        }
    }

这是原始解决方案与我的解决方案的输出。原方案未能缩短最后一个路径元素:

N:\DIRECT~1\tmp\temp\ASDFAS~1\[asdfas] asdfasd asd asdfasdf ~fdfsdfdfdsfdfdfdfdfd~ TTTm7-9 [RR 1234a5678 A.888 OKOK]a
N:\DIRECT~1\tmp\temp\ASDFAS~1\_ASDFA~1.888

【讨论】:

    猜你喜欢
    • 2014-06-29
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多