Reading single InputStream from multiple methods

Deadly 提交于 2019-12-02 10:08:22

The problem is in creating two BufferedReaders on top of the same Reader. When you read data from BufferedReader, it's likely to read more than the data it returns, into its buffer (hence the name). In other words, even though you've only read a single line from the BufferedReader, the InputStreamReader may have had a lot more data read from it - so if you read again from that InputStreamReader then you'll miss that data. The data has effectively been sucked from the InputStreamReader to the BufferedReader, so the only way of getting it out to client code is to read it from that BufferedReader.

In other words, your claim that:

Nope. fetchHeaders() only reads first line of CSV containing Headers.

is incorrect. It only uses that much data, but it reads more from the InputStreamReader.

As Ilya said, you should only create one BufferedReader on top of the original InputStreamReader, and pass that into both methods.

fetchHeaders can then use that BufferedReader to read a line, and processContentRows can do what it likes with the BufferedReader at that point - it's just a Reader as far as it needs to know.

So to modify Ilya's example slightly:

public static void main(String[] args) {
  FileInputStream fis = new FileInputStream("FileName.CSV");
  BufferedInputStream bis = new BufferedInputStream(fis);
  InputStreamReader isr = new InputStreamReader(bis);
  BufferedReader br = new BufferedReader(isr);

  processCSV(br);
}

private static void processCSV(BufferedReader reader) {
  fetchHeaders(reader);
  processContentRows(reader);
}

private static void fetchHeaders(BufferedReader reader) {
   // Use reader.readLine() here directly... do *not* create
   // another BufferedReader on top.
}

private static void processContentRows(Reader reader) {
  // This could be declared to take a BufferedReader if you like,
  // but it doesn't matter much.
}

You're not doing anything wrong. Just make sure that the method opening a stream/reader also closes it, in a finally block.

If you need a BufferedReader, I think you need to create it in in main method:

main() {
  FileInputStream fis = new FileInputStream("FileName.CSV");
  BufferedInputStream bis = new BufferedInputStream(fis);
  InputStreamReader isr = new InputStreamReader(bis);
  BufferedReader br = new BufferedReader(isr);

  processCSV(br);
}

processCSV(Reader isr) {
  fetchHeaders(isr);
  processContentRows(isr);
}

fetchHeaders(Reader isr) {
  //Use BufferedReader to retrieve first line of CSV
  //Even tried mark() and reset() here
}

processContentRows(Reader isr) {
  //Cannot read the values, fetches null from InputStream :(
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!