我已经在一个类的单个方法中初始化了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 :( }
我在这里做错什么了吗?有什么方法可以在不同的方法调用之间重用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); } } } }
问题在于在BufferedReader同一对象上创建两个Reader。当您从中读取数据时BufferedReader,它可能会读取比返回的数据更多的内容到其缓冲区中(因此而得名)。换句话说,即使您仅从中读取了一行BufferedReader,InputStreamReader可能仍从中读取了很多数据- 因此,如果您再次读取 该行InputStreamReader,则会丢失该数据。该数据有效地被吸 从 该InputStreamReader 到 了BufferedReader,因此让出来给客户端代码的唯一方法是从阅读它BufferedReader。
BufferedReader
Reader
InputStreamReader
换句话说,您声称:
不。fetchHeaders()仅读取包含标题的CSV的第一行。
是不正确的。它仅 使用 那么多的数据,但会 从中读取 更多数据InputStreamReader。
正如Ilya所说,您只能BufferedReader在原始之上创建一个InputStreamReader,并将其传递给这两种方法。
fetchHeaders然后可以使用它BufferedReader来读取一行,然后processContentRows可以使用来完成所需的操作BufferedReader-这只是Reader它需要知道的内容。
fetchHeaders
processContentRows
因此,稍微修改一下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. }