我已经在类中的单个方法中初始化了一个InputStream,并将其传递给下一个方法进行处理。 InputStream基本上封装了CSV文件以供处理。
另一种方法调用2个不同的方法,传入相同的InputStream,一个用于检索头,另一个用于处理内容。结构看起来如下所示:
main() {
FileInputStream fis = new FileInputStream("FileName.CSV");
BufferedInputStream bis = new BufferedInputStream(fis);
InputStreamReader isr = new InputStreamReader(bis);
processCSV(isr);
}
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 :(
}
我在这里做错了吗?有什么办法可以在不同的方法调用中重用InputStream。
我正在制定可以模仿以下问题的完整程序:
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
public class MarkResetTest
{
public static void main(String a[])
{
FileInputStream fis = null;
BufferedInputStream bis = null;
InputStreamReader isr = null;
BufferedReader br = null;
BufferedReader br2 = null;
try {
fis = new FileInputStream("C:/Test/Customers.csv");
bis = new BufferedInputStream(fis);
isr = new InputStreamReader(bis, "Unicode");
System.out.println("BR readLine()");
br = new BufferedReader(isr);
//System.out.println(br.markSupported());
br.mark(1000);
System.out.println(br.readLine());
br.reset();
//System.out.println(br.readLine());
System.out.println("BR2 readLine()");
br2 = new BufferedReader(isr);
System.out.println(br2.readLine());
}
catch(Exception e) {
System.out.println("Exception::" + e);
}
finally {
try {
br.close();
isr.close();
bis.close();
fis.close();
}
catch(Exception e) {
System.out.println("Exception while closing streams :: " + e);
}
}
}
}
答案 0 :(得分:4)
问题在于在同一BufferedReader
之上创建两个Reader
。当您从BufferedReader
读取数据时,它可能读取的数据超过它返回的数据,进入其缓冲区(因此名称)。换句话说,即使您只读取了BufferedReader
中的一行,InputStreamReader
也可能从中读取了更多数据 - 因此,如果您再次从中读取 { {1}} 然后你会错过这些数据。数据已经从InputStreamReader
<{1}}实际上被吸引,因此将其发送到客户端代码的唯一方法是读取它来自InputStreamReader
。
换句话说,您声称:
不。 fetchHeaders()只读取包含标题的CSV的第一行。
不正确。只有使用那么多数据,但从BufferedReader
读取更多。
正如Ilya所说,你应该只在原BufferedReader
之上创建一个InputStreamReader
,并将其传递给两种方法。
BufferedReader
然后可以使用InputStreamReader
来读取一行,而fetchHeaders
可以使用BufferedReader
执行它所喜欢的行 - 它只是{{1}只要它需要知道。
所以稍微修改Ilya的例子:
processContentRows
答案 1 :(得分:1)
你没有做错任何事。只需确保打开流/阅读器的方法也会在finally块中关闭它。
答案 2 :(得分:1)
如果你需要一个BufferedReader,我认为你需要在main方法中创建它:
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 :(
}