Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从多个方法读取单个InputStream_Java_Inputstream_Java Io - Fatal编程技术网

Java 从多个方法读取单个InputStream

Java 从多个方法读取单个InputStream,java,inputstream,java-io,Java,Inputstream,Java Io,我已经在类中的单个方法中初始化了InputStream,并将其传递给下一个方法进行处理。InputStream本质上封装了用于处理的CSV文件 另一个方法调用两个不同的方法,传递相同的InputStream,一个用于检索头,另一个用于处理内容。结构如下所示: main() { FileInputStream fis = new FileInputStream("FileName.CSV"); BufferedInputStream bis = new BufferedInputStrea

我已经在类中的单个方法中初始化了InputStream,并将其传递给下一个方法进行处理。InputStream本质上封装了用于处理的CSV文件

另一个方法调用两个不同的方法,传递相同的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);
            }
        }
    }
  }

你没有做错什么。只需确保打开流/读取器的方法也会在finally块中关闭它。

您没有做错任何事情。只需确保打开流/读取器的方法也会在finally块中关闭它。

如果需要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 :(
}

如果您需要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 :(
}

问题在于在同一个
读取器
上创建两个
缓冲读取器。当您从
BufferedReader
读取数据时,它很可能会将比返回的数据更多的数据读入其缓冲区(因此得名)。换句话说,即使您只从
BufferedReader
读取了一行数据,
InputStreamReader
可能从中读取了更多的数据-因此,如果您再次从该
InputStreamReader
读取数据,您将丢失该数据。数据已经从
InputStreamReader
有效地被吸入到
BufferedReader
,因此将数据输出到客户端代码的唯一方法是从该
BufferedReader
读取数据

换句话说,您的声明:

没有。fetchHeaders()只读取包含标题的CSV的第一行

这是不正确的。它只使用了那么多数据,但它从
InputStreamReader
读取的数据更多

正如Ilya所说,您应该只在原始的
InputStreamReader
上创建一个
BufferedReader
,并将其传递到这两个方法中

fetchHeaders
然后可以使用该
BufferedReader
读取一行,而
processContentRows
此时可以使用
BufferedReader
执行它喜欢的操作-就其所需知,它只是一个
Reader

因此,稍微修改一下伊利亚的例子:

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.
}

问题在于在同一个
读取器
上创建两个
缓冲读取器。当您从
BufferedReader
读取数据时,它很可能会将比返回的数据更多的数据读入其缓冲区(因此得名)。换句话说,即使您只从
BufferedReader
读取了一行数据,
InputStreamReader
可能从中读取了更多的数据-因此,如果您再次从该
InputStreamReader
读取数据,您将丢失该数据。数据已经从
InputStreamReader
有效地被吸入到
BufferedReader
,因此将数据输出到客户端代码的唯一方法是从该
BufferedReader
读取数据

换句话说,您的声明:

没有。fetchHeaders()只读取包含标题的CSV的第一行

这是不正确的。它只使用了那么多数据,但它从
InputStreamReader
读取的数据更多

正如Ilya所说,您应该只在原始的
InputStreamReader
上创建一个
BufferedReader
,并将其传递到这两个方法中

fetchHeaders
然后可以使用该
BufferedReader
读取一行,而
processContentRows
此时可以使用
BufferedReader
执行它喜欢的操作-就其所需知,它只是一个
Reader

因此,稍微修改一下伊利亚的例子:

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.
}

请在fetchHeaders和processContentRows中显示一些代码。例如,fetchHeaders是否真的会一直读取到数据结束,而不是在报头结束时停止读取?否。fetchHeaders()只读取包含标题的CSV的第一行。语句是br.readLine(),它不在循环中。那么,你能想出一个简短但完整的程序来演示这个问题吗?嗨,Jon,我用示例程序编辑了我的文章。您现在可以签出吗?请在fetchHeaders和processContentRows中显示一些代码。例如,fetchHeaders是否真的会一直读取到数据结束,而不是在报头结束时停止读取?否。fetchHeaders()只读取包含标题的CSV的第一行。语句是br.readLine(),它不在循环中。那么,你能想出一个简短但完整的程序来演示这个问题吗?嗨,Jon,我用示例程序编辑了我的文章。您现在可以签出吗?流在main()中打开,在main()中关闭。其他方法只是使用适当的读取方法来读取内容。流在main()中打开,在main()中关闭。其他方法只是使用适当的读取方法来读取内容。问题在于fetchHeaders()使用的是BufferedReader。processContentRows()使用其他读取器来处理这些行。好的,BufferedReader也是一个读取器。您可以像使用InputStreamReader一样将其包装到自定义读取器中。这也可能会给您带来一些性能改进(因为缓冲)。@mayur:Ilya的回答是正确的,但我添加了我自己的代码示例,更详细一些,更完整一些(IMO)。问题在于fetchHeaders()使用的是BufferedReader。processContentRows()使用其他读取器来处理这些行。好的,BufferedReader也是一个读取器。您可以像使用InputStreamReader一样将其包装到自定义读取器中。这也可能会给您带来一些性能改进(因为缓冲)。@mayur:Ilya的回答是正确的,但我添加了我自己的代码示例,更详细一些,更完整一些(IMO)