使用 Java 复制文件会跳过连续两个空格的文件名
Copying files with Java skips file names with two spaces in a row
这有点令人困惑。以下批处理片段导致复制这两个文件:
xcopy "C:\Source\Spaces1 [ ].txt" "C:\Target\" /Y
xcopy "C:\Source\Spaces2 [ ].txt" "C:\Target\" /Y
以下使用流的 Java 片段也会导致复制两个文件:
public static void main(final String args[]) throws IOException
{
final File source1 = new File("C:\Source", "Spaces1 [ ].txt");
final File target1 = new File("C:\Target", "Spaces1 [ ].txt");
fileCopy(source1, target1);
final File source2 = new File("C:\Source", "Spaces2 [ ].txt");
final File target2 = new File("C:\Target", "Spaces2 [ ].txt");
fileCopy(source2, target2);
}
public static void fileCopy(final File source, final File target) throws IOException
{
try (InputStream in = new BufferedInputStream(new FileInputStream(source));
OutputStream out = new BufferedOutputStream(new FileOutputStream(target));)
{
final byte[] buf = new byte[4096];
int len;
while (0 < (len = in.read(buf)))
{
out.write(buf, 0, len);
}
out.flush();
}
}
但是,在此代码段中,未复制其中一个文件(跳过带有双空格的文件):
public static void main(final String args[]) throws Exception
{
final Runtime rt = Runtime.getRuntime();
rt.exec("xcopy \"C:\Source\Spaces1 [ ].txt\" \"C:\Target\\" /Y").waitFor();
// This file name has two spaces in a row, and is NOT actually copied
rt.exec("xcopy \"C:\Source\Spaces2 [ ].txt\" \"C:\Target\\" /Y").waitFor();
}
怎么回事?这将用于从谁知道什么来源复制文件,人们可以在其中输入他们喜欢的任何内容。文件名已清理,但谁来清理连续的两个空格?我在这里错过了什么?
目前使用 Java 8,但 Java 6 和 7 给出相同的结果。
Javadoc 里都有。
Runtime#exec(String)
代表 Runtime#exec(String,null,null)
exec(String,null,null)
代表 exec(String[] cmdarray,envp,dir)
然后
More precisely, the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
此时两个 space 丢失,当命令字符串由 OS 重新组合时变成一个 space。
这有点令人困惑。以下批处理片段导致复制这两个文件:
xcopy "C:\Source\Spaces1 [ ].txt" "C:\Target\" /Y
xcopy "C:\Source\Spaces2 [ ].txt" "C:\Target\" /Y
以下使用流的 Java 片段也会导致复制两个文件:
public static void main(final String args[]) throws IOException
{
final File source1 = new File("C:\Source", "Spaces1 [ ].txt");
final File target1 = new File("C:\Target", "Spaces1 [ ].txt");
fileCopy(source1, target1);
final File source2 = new File("C:\Source", "Spaces2 [ ].txt");
final File target2 = new File("C:\Target", "Spaces2 [ ].txt");
fileCopy(source2, target2);
}
public static void fileCopy(final File source, final File target) throws IOException
{
try (InputStream in = new BufferedInputStream(new FileInputStream(source));
OutputStream out = new BufferedOutputStream(new FileOutputStream(target));)
{
final byte[] buf = new byte[4096];
int len;
while (0 < (len = in.read(buf)))
{
out.write(buf, 0, len);
}
out.flush();
}
}
但是,在此代码段中,未复制其中一个文件(跳过带有双空格的文件):
public static void main(final String args[]) throws Exception
{
final Runtime rt = Runtime.getRuntime();
rt.exec("xcopy \"C:\Source\Spaces1 [ ].txt\" \"C:\Target\\" /Y").waitFor();
// This file name has two spaces in a row, and is NOT actually copied
rt.exec("xcopy \"C:\Source\Spaces2 [ ].txt\" \"C:\Target\\" /Y").waitFor();
}
怎么回事?这将用于从谁知道什么来源复制文件,人们可以在其中输入他们喜欢的任何内容。文件名已清理,但谁来清理连续的两个空格?我在这里错过了什么?
目前使用 Java 8,但 Java 6 和 7 给出相同的结果。
Javadoc 里都有。
Runtime#exec(String)
代表 Runtime#exec(String,null,null)
exec(String,null,null)
代表 exec(String[] cmdarray,envp,dir)
然后
More precisely, the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
此时两个 space 丢失,当命令字符串由 OS 重新组合时变成一个 space。