Java 在Windows上写入名称无效的文件时出现意外行为

Java 在Windows上写入名称无效的文件时出现意外行为,java,io,filesystems,Java,Io,Filesystems,在我的一个项目中,当使用Java将文件写入MS Windows中的本地文件系统时,我遇到了一个非常意外的行为。 文件名由应用程序生成,包含无效字符“:”。程序没有对此进行防范(现在是这样),但我希望在将内容写入该文件时出现IOException。然而,情况要复杂得多 以下是我所经历的一个SSCE: import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io

在我的一个项目中,当使用Java将文件写入MS Windows中的本地文件系统时,我遇到了一个非常意外的行为。 文件名由应用程序生成,包含无效字符“:”。程序没有对此进行防范(现在是这样),但我希望在将内容写入该文件时出现IOException。然而,情况要复杂得多

以下是我所经历的一个SSCE:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class FileWriter {

  public static void main(String[] args) throws IOException {
    File home = new File(System.getProperty("user.dir"));
    final String fileName = "invalidf:ile.txt";

    // Some cleanup if you rerun the example
    File otherFile = new File(home, "invalidf");
    if (otherFile.exists()) {
      assertTrue(otherFile.delete());
    }
    File file = new File(home, fileName);
    if (file.exists()) {
      assertTrue(file.delete());
    }

    // The real scenario. Writing some content to an illegal file name
    FileOutputStream out = new FileOutputStream(file);
    final String content = "some test content";
    out.write(content.getBytes());
    out.close();

    // Since the write operation does not throw an exception, it is expected some file has been written
    assertTrue(file.isFile());
    assertTrue(file.canRead());

    // This should usually throw an exception since the file was deleted in the cleanup section.
    assertTrue(otherFile.exists());

    // Now we try to read the data and make sure it really got stored.
    FileInputStream in = new FileInputStream(file);
    assert in.available() > 0;
    byte[] fileContent = new byte[in.available()];
    assertTrue(in.read(fileContent) == content.getBytes().length);
    assertTrue(Arrays.equals(fileContent, content.getBytes()));
  }

  private static void assertTrue(boolean flag) {
    if (!flag) {
      throw new RuntimeException("Assertion failed!");
    }
  }
}
那么,问题是什么: Windows将按预期列出一个新文件
invalidf
,而不是
invalidf:ile.txt
。文件大小显示为0字节,读取该文件(使用编辑器和Java代码)不会返回任何内容。最初编写的文件似乎不存在

但是,使用Java读取文件invalidf:ile.txt会显示最初编写的内容(如上面的代码所示)

那么这里的问题是什么?似乎有两个文件可用。一个可见但看似空的文件和一个包含真实内容的“隐藏”文件。但是,如果我删除空文件,“隐藏”文件也无法再访问。因此,文件系统似乎将这两个文件视为相同的文件

这可能与我使用的Windows和Java版本有关(使用Java 6和Windows 7进行测试)。

搜索“Windows备用数据流”。解释

备用数据流是附加到文件的数据流,但与主文件内容无关。似乎“:”是在Windows中指定广告的方式。从上面的链接中,您可以读取备用流的内容,如下所示:

notepad invalidf:ile.txt
搜索“Windows备用数据流”。解释

备用数据流是附加到文件的数据流,但与主文件内容无关。似乎“:”是在Windows中指定广告的方式。从上面的链接中,您可以读取备用流的内容,如下所示:

notepad invalidf:ile.txt
搜索“Windows备用数据流”。解释

备用数据流是附加到文件的数据流,但与主文件内容无关。似乎“:”是在Windows中指定广告的方式。从上面的链接中,您可以读取备用流的内容,如下所示:

notepad invalidf:ile.txt
搜索“Windows备用数据流”。解释

备用数据流是附加到文件的数据流,但与主文件内容无关。似乎“:”是在Windows中指定广告的方式。从上面的链接中,您可以读取备用流的内容,如下所示:

notepad invalidf:ile.txt

每天都要学习新的东西。非常感谢你的回答。每天都要学习新的东西。非常感谢你的回答。每天都要学习新的东西。非常感谢你的回答。每天都要学习新的东西。非常感谢你的回答。