【问题标题】:What will readAllLines return if the file does not exist?如果文件不存在,readAllLines 会返回什么?
【发布时间】:2016-07-13 16:50:21
【问题描述】:

oracle 文档说here Files.readAllLines(Path path, Charset cs) 方法将文件中的行作为List<String> 返回。
如果文件不存在,它会返回什么?还有List<String> 的哪个实现会返回?

【问题讨论】:

  • IOException,可能,List<String> 类型故意未指定且可能会更改。 (不过,我敢打赌,unmodifiableListArrayList 的包装器。)
  • @LouisWasserman:所以我不能确定对于返回的ListList.get() 是 O(n) 还是 O(1)?
  • @ln78 我不会担心这个;假设它是 O(1),你应该会感到相当舒服,而不是它是否可修改。
  • 是的,虽然我怀疑它会是 ArrayList。
  • 你可以做List<String> randomList = list instanceof RandomAccess ? list : new ArrayList<>(list);

标签: java file


【解决方案1】:

这里是Files#readAllLines(Path, Charset)抛出的异常

它实际上使用 try-with-ressources 实例化 BufferedReader 并以 path 作为参数。如果文件不存在,则IOException 会在构造函数中被它抛出。

投掷:

java.io.IOException 如果从文件读取时发生 I/O 错误或 读取格式错误或无法映射的字节序列

java.lang.SecurityException 在默认提供者的情况下,还有一个 安装安全管理器,调用 checkRead 方法 检查文件的读取权限。


ArrayList<String> 用作List<String> 的精确实现

public static List<String> readAllLines(Path path, Charset cs) throws IOException {
    try (BufferedReader reader = newBufferedReader(path, cs)) {
        List<String> result = new ArrayList<>();           <-------- HERE
        for (;;) {
             String line = reader.readLine();
             if (line == null)
                 break;
             result.add(line);
        }
        return result;
    }
}

【讨论】:

    【解决方案2】:

    如果文件不存在会返回什么?

    它不会“返回”任何东西。 正如JavaDoc 所说,readAllLines 方法将在 I/O 错误的情况下抛出 IOException

    具体来说,当文件不存在时,我正在使用的 JDK 8 的实现恰好抛出一个 java.nio.file.NoSuchFileException,它是 IOException 的子类。

    还有List&lt;String&gt; 的哪个实现会返回?

    这真的不是你关心的问题。这就是接口和封装存在的原因,所以你不要往里看。重要的是它是一个遵守List 接口契约的对象。

    如果你必须知道,你可以通过在返回的对象上调用.getClass() 来检查。我正在使用的 JDK 8 的实现恰好返回 java.util.ArrayList。另一个实现可能会返回其他内容。正如我之前提到的,我们甚至不应该尝试查看它是什么,以避免任何破坏封装的风险。

    【讨论】:

    • 实际上,根据Javadoc,“列表是否可修改取决于实现,因此未指定”,尽管在我的实现中也是java.util.ArrayList
    【解决方案3】:

    简单到可以测试吗?

    Exception in thread "main" java.nio.file.NoSuchFileException
    

    关于返回值的实际类型。返回签名只是说列表,这就是你可以信任的。说了这么多,目前的Oracle类库返回ArrayList:

    List<String> readAllLines = Files.readAllLines(path, Charset.defaultCharset());
    System.out.println(readAllLines.getClass());
    

    给出输出:

    class java.util.ArrayList
    

    在源代码中可以看到:

    List<String> result = new ArrayList<>();
    

    【讨论】:

      【解决方案4】:

      如果文件不存在,它将抛出NoSuchFileException。您可以详细了解NoSuchFileExceptions here

      【讨论】:

      • 其实没有,至少在当前的任何jvm中都没有,它会抛出一个java.nio.file.NoSuchFileException
      • 您可能正在使用 JDK7 或 JDK8。
      • 嗯,你的回答最初只是明确地说明了 FileNotFoundException,我回答说不在任何当前的 jvm 中。即使是 7 也正式结束生命。
      • Java 6 中不存在 Files 类和 readAllLines api。
      • @MattiasIsegranBergander,你是对的..我犯了错误。 Java 6 中既不存在 Files 类也不存在 readAllLines api。谢谢
      猜你喜欢
      • 2013-02-27
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2022-01-23
      相关资源
      最近更新 更多