I have initialized an InputStream in a single method in a class and passing it to next method for processing. The InputStream essentially encapsulates CSV file for processing.
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 :(
}
The problem is in creating two BufferedReader
s 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.
}