【问题标题】:Java - File being read returns nullJava - 正在读取的文件返回 null
【发布时间】:2014-08-03 17:40:13
【问题描述】:

您好,我正在将一个文件加载到我的程序中并分配每个值(存储在一个新行上的数组中)我似乎无法发现为什么保存文件内容的数组在每个索引中为空。

    private void readAndProcessWords() {
    try {
        FileReader _fr = new FileReader(FILEPATH);
        BufferedReader textReader = new BufferedReader(_fr);

        int numLines = getNumLines(textReader);
        String[] words = new String[numLines];

        for(int i=0;i<numLines;i++){
            words[i] = textReader.readLine();
            System.out.println(words[i]);
        }
        //clears memory reserved for this buffered reader
        textReader.close();

    } catch(IOException e) {
        System.out.println(e);
    }
}

private int getNumLines(BufferedReader textReader) throws IOException{
    String line;
    int numLines =0;

    while((line = textReader.readLine()) != null){
        numLines++;
    }
    return numLines;    
}
}

解决方案:在循环上方添加以下代码以“重置”文件阅读器

_fr = new FileReader(FILEPATH);
        textReader = new BufferedReader(_fr);

【问题讨论】:

  • 欢迎来到 Stack Overflow,请拨打Tour。寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。见How to create a Minimal, Complete, and Verifiable example
  • 使用调试器来跟踪执行。
  • while((line = textReader.readLine()) != null){ 是怎么想的?
  • 我会声明您已经使用 getNumeLines() 使用了您的文件,因此在开始解析行时您处于文件末尾。
  • 考虑使用 Guava 和类似下面的代码: final URL resource = Resources.getResource("path/to/file.txt"); final List 行 = Resources.readLines(resource, Charset.defaultCharset());

标签: java arrays bufferedreader


【解决方案1】:

最简单的解决方案是重新创建 Reader,问题是调用 getNumLines() 会将 BufferedReader 中的位置移动到文件末尾。

BufferedReader textReader = new BufferedReader(_fr);
int numLines = getNumLines(textReader); // <-- textReader is at EOF after this.
textReader.close();
textReader = new BufferedReader(_fr);

【讨论】:

  • 感谢大家的想法!上面的建议确实导致了这个问题。我修正了这个问题的修复。我需要添加一行来创建一个新的文件阅读器。
  • 只是提醒一下,当您关闭 textReader 时,您可能希望在 finally 块中执行此操作,或者在 Java 7 中使用 try-with 资源来在异常情况下正确清理资源。
【解决方案2】:

不是读取文件两次来获取行数(这很慢,烦人,并且如果文件在两次调用之间发生更改将不起作用),而是将行读入可变大小列表:

private void readAndProcessWords() {
    try {
        FileReader _fr = new FileReader(FILEPATH);
        BufferedReader textReader = new BufferedReader(_fr);

        List<String> words = new ArrayList<>();
        String line;
        while ((line = textReader.readLine()) != null) {
            words.add(line);
        }
        textReader.close();

        for (String word : words) {
            System.out.println(word);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

好消息:这个功能already exists,所以你不需要重写它。

private void readAndProcessWords() {
    try {
        List<String> words = Files.readAllLines(Paths.get(FILEPATH));

        for (String word : words) {
            System.out.println(word);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

【讨论】:

    【解决方案3】:

    由于缓冲阅读器是一个对象,因此您将其作为对 getNumLines() 的引用而不是作为副本传递,因此当您在发送到 getNumLines() 的同一个缓冲阅读器上 .readLine() 时,您最终会得到一个 null因为您已经将.readLine() 运行到了极限。

    运行getNumLines() 后,关闭并使用新的缓冲阅读器重新打开文档。

    我还记得有一个 Mark()Recall() 在 java 中用于缓冲读取器的方法,也可以作为一种解决方法。

    我觉得像。

            FileReader _fr = new FileReader(FILEPATH);
            BufferedReader textReader = new BufferedReader(_fr);
    
    
            textReader.Mark();
    
    
            int numLines = getNumLines(textReader);
    
    
            textReader.Recall();
    
    
            String[] words = new String[numLines];
    
            for(int i=0;i<numLines;i++)
            {
                words[i] = textReader.readLine();
                System.out.println(words[i]);
            }
            //clears memory reserved for this buffered reader
            textReader.close();
    

    【讨论】:

      猜你喜欢
      • 2020-03-16
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 2011-05-14
      • 2019-08-29
      相关资源
      最近更新 更多