Osmund Francis
Osmund Francis

Reputation: 821

How to get short-filenames in Windows using Java?

How to get the short-filename for a long-filename in Windows using Java?

I need to determine the short-filenames of files, stored on a Windows system, using Java(tm).

Upvotes: 10

Views: 5533

Answers (2)

John Ng
John Ng

Reputation: 1

I found a slight problem Osmund's solution. It doesn't work properly for this file name for some reason:

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

I'm not really sure why exactly. But if you run the command a slightly different way (using ProcessBuilder), it works. Here is the new code (I am using BufferedReader to read the output, it is much cleaner).

    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();
        }
    }

This is the output of the original solution vs my solution. The original solution fails to shorten the last path element:

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

Upvotes: -1

Osmund Francis
Osmund Francis

Reputation: 821

Self Answer

There are related questions with related answers. I post this solution, however, because it uses Java(tm) code without the need for external libraries. Additional solutions for different versions of Java and/or Microsoft(R) Windows(tm) are welcome.

Main Concept

Main concept lies in calling CMD from Java(tm) by means of the runtime class:

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

Solution

Tested on Java SE 7 running on Windows 7 system (Code has been reduced for brevity).

    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;
}

Upvotes: 10

Related Questions