mav*_*ckm 0 java inputstream java-io
我已经在类中的单个方法中初始化了一个InputStream,并将其传递给下一个方法进行处理。InputStream本质上封装了用于处理的CSV文件。
另一种方法调用传入同一 InputStream 的 2 个不同方法,一个用于检索标头,另一个用于处理内容。该结构如下所示:
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 :(
}
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么吗?有什么方法可以在不同的方法调用之间重用 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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于BufferedReader在同一个 s 之上创建两个 s Reader。当您从 读取数据时BufferedReader,它可能会读取比返回的数据更多的数据到其缓冲区中(因此得名)。换句话说,即使您只从 中读取了一行BufferedReader,也InputStreamReader可能从中读取了更多数据 - 因此,如果您再次从中InputStreamReader读取,那么您将错过该数据。数据已被有效地从 吸到,因此将其发送到客户端代码的唯一方法就是从 读取数据。InputStreamReader BufferedReaderBufferedReader
换句话说,您的主张是:
没有。fetchHeaders() 仅读取包含标题的 CSV 的第一行。
是不正确的。它只使用那么多数据,但它从InputStreamReader.
BufferedReader正如 Ilya 所说,您应该只在原始的基础上创建一个InputStreamReader,并将其传递给这两种方法。
fetchHeaders然后可以使用它BufferedReader来读取一行,并且可以在此时processContentRows执行它喜欢的操作- 这只是它需要知道的范围。BufferedReaderReader
所以稍微修改一下 Ilya 的例子:
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.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6132 次 |
| 最近记录: |