Java:在一个InputStream上使用两个读取器

Java:在一个InputStream上使用两个读取器,java,inputstream,bufferedreader,buffering,Java,Inputstream,Bufferedreader,Buffering,我的应用程序可以编辑一种称为TDAEntry的文本文件。每个这样的条目都基于另一种描述其格式的文件类型,称为TDAForm。TDAEntry文本文件中的第一行是它所属表单的名称,然后是其余数据(以文本形式) 现在打开这样一个文件,我的代码如下: InputStream entryInput = new FileInputStream(file); BufferedReader entryReader = new BufferedReader( new InputStreamReader

我的应用程序可以编辑一种称为TDAEntry的文本文件。每个这样的条目都基于另一种描述其格式的文件类型,称为TDAForm。TDAEntry文本文件中的第一行是它所属表单的名称,然后是其余数据(以文本形式)

现在打开这样一个文件,我的代码如下:

InputStream entryInput = new FileInputStream(file);

BufferedReader entryReader = new BufferedReader(
    new InputStreamReader(entryInput)); // PROBLEMATIC #1

String formName = entryReader.readLine();

TDAForm form = new TDAForm(formName);

// create an entry with the right form and the data which follows in entryInput
TDAEntry entry = new TDAEntry(form, entryInput); // PROBLEMATIC #2
问题出在这里。阅读
InputStreamReader
的源代码时,您将最终阅读此类的代码:

它是缓冲的,这意味着它可以提前读取8000字节。这会导致第“Problemble#2”行的
InputStream
为空且位于错误位置,而我希望它继续运行,就像只读取了文件的第一行一样。在TDAEntry的构造函数中,我可能希望在流上构造另一种读取器,或者做其他事情

一个显而易见的解决方案是编写一个新的解码器,它不会占用前面的字节。但我想知道是否有更简单的方法来实现这一点。你会如何解决这个问题,或者你会建议另一种编程结构来完成同样的事情


非常感谢

只要把阅读器传进来就行了。它将继续阅读它停止的地方:

TDAEntry entry = new TDAEntry(form, entryReader); 

把读者传进来就行了。它将继续阅读它停止的地方:

TDAEntry entry = new TDAEntry(form, entryReader); 

如果只想限制缓冲区,则不需要编写自己的类。您可以使用第二个构造函数,即
newbufferedreader(newinputstreamreader(entryInput),20)
以限制缓冲区大小


这并不一定是处理这个问题的最佳方式。基本上,在半空中切换流是一个非常糟糕的主意。您可以创建自己的InputStream实现来读取头和条目。

如果您只想限制缓冲区,则不需要编写自己的类。您可以使用第二个构造函数,即
newbufferedreader(newinputstreamreader(entryInput),20)
以限制缓冲区大小


这并不一定是处理这个问题的最佳方式。基本上,在半空中切换流是一个非常糟糕的主意。您可以创建自己的InputStream实现来读取头和条目。

您可以尝试将FileInputStream包装到BufferedInputStream中,因为缓冲版本支持mark()和reset()。

您可以尝试将FileInputStream包装到BufferedInputStream中,因为缓冲版本支持mark()和reset()。

执行此操作的最佳方法是关闭缓冲读取器并手动读取第一行。如果不重新实现,就无法控制缓冲读取器的缓冲方式。这是行不通的,因为事实证明InputStreamReader实际上也是缓冲的。不幸的是,我在编写自己的行读取程序后发现,字节仍在进行缓冲。最好的方法是杀死缓冲读取器并手动读取第一行。如果不重新实现,就无法控制缓冲读取器的缓冲方式。这是行不通的,因为事实证明InputStreamReader实际上也是缓冲的。不幸的是,我在编写了自己的行读取程序后发现,字节仍然被缓冲。我考虑过这一点,但我可能想在另一种流上构建TDAEntry,而不是读卡器。但是也许我应该为它创建一个单独的构造函数,或者什么的?是的,你可以有两个构造函数,一个接受读取器,另一个接受InputStream或者你想要的任何东西。我现在将这个标记为正确的,因为这是我将要运行的解决方案。我早该意识到我可以有不止一个构造函数。谢谢我考虑过这一点,但我可能想在另一种流上构建TDAEntry,它不是阅读器。但是也许我应该为它创建一个单独的构造函数,或者什么的?是的,你可以有两个构造函数,一个接受读取器,另一个接受InputStream或者你想要的任何东西。我现在将这个标记为正确的,因为这是我将要运行的解决方案。我早该意识到我可以有不止一个构造函数。谢谢第一个解决方案不起作用,因为InputStreamReader实际上也是缓冲的。但是你的第二个想法很有趣,尽管如果我自己制作InputStream,不使用阅读器的字符解码功能似乎有点浪费。第一个解决方案不起作用,因为InputStreamReader实际上也是缓冲的。但是你的第二个想法很有趣,尽管如果我自己制作输入流,不使用阅读器的字符解码功能似乎有点浪费。