readLine()返回null,即使文件有内容



numberOfFields((方法应该找出csv文件的特定行中存在的列数。我预计是7,但我的输出是0;这就是我初始化cols的方式。所以我在while循环中使用了system.out.println((,我发现while循环没有被输入。我的文件有很多行文本,所以我不明白为什么readLine((返回null。不知道我还有什么错。

public class CSVReader {
public BufferedReader bR1;
public CSVReader(String fileName) throws IOException {
bR1 = new BufferedReader(new FileReader(fileName));
}

public int numberOfFields(int row) throws IOException {
int rows = 1;
while (rows < row) {
bR1.readLine();
rows++;
}
int cols = 0;
String line;
while ((line=bR1.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",");
while (st.hasMoreElements()) {
st.nextToken();
cols++;
}
}
return cols;

在我看来,可能有两个原因:

  1. 您给出的参数row超过了文件的行号
  2. 您的fileName错误

我建议您在第一个while循环中添加System.out.println(bR1.readLine),看看发生了什么。

一个InputStream只能读取一次。

如果多次调用numberOfFields(),则除第一次调用外的所有调用都将失败,因为bR1不再位于文件的开头。它实际上位于文件的末尾,因为第一个调用离开了读取器。

让每个方法打开自己的流,而不是在构造函数中打开流。

在以下方面,这些问题已经得到解决:

  • 使用try with resources正确处理流的关闭。

    Try with resources是在Java 7中添加的,所以除非你运行的是Java的古老版本,否则绝对没有充分的理由使用它

  • 将代码更改为只计算请求行的列,而不计算所有剩余行的列。

  • StringTokenizer的使用已被regex所取代。正如StringTokenizer的javadoc所说:

    StringTokenizer是一个遗留类,由于兼容性原因而被保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人使用Stringsplit方法或java.util.regex包。

public class CSVReader {
public final String fileName;
public CSVReader(String fileName) {
this.fileName = fileName;
}
public int numberOfFields(int row) throws IOException {
try (BufferedReader bR1 = new BufferedReader(new FileReader(this.fileName))) {
// Skip row-1 rows
for (int rows = 1; rows < row; rows++) {
bR1.readLine();
}

// Count number of columns in next line, if available
String line = bR1.readLine();
return (line == null ? 0 : line.split(",", -1).length);
}
}

相关内容

  • 没有找到相关文章