我想逐行读两遍InputStream
。我在第一遍中使用以下代码:
LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
String line;
String eventId = null;
Set<Integer> artistIds = new HashSet<Integer>();
while((line = reader.readLine())!=null) {
// process first pass
}
// how do I reset reader so that I can read from the beginning again?
有reset()
方法可用,但它会重置为文件中的最后一个mark
。我不太明白这意味着什么。我可以使用mark
和reset
来实现reset to beginning
行为吗?像
LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
reader.mark(0); // mark at the 0th position
// process first pass: repeated calls to readline() until EOF
reader.reset(); // reset to 0th position??
// process second pass
在我的本地机器上进行测试时,我在第二次传递之前reader.close()
- 并且它有效。但是,当我在HDFS中执行此操作时,reader.close()
可能也会关闭HDFS InputStream,并且我得到java.io.IOException: Stream closed
例外。
答案 0 :(得分:1)
标记并重置工作,但不要调用.mark(0)
将读取超前限制设置为0,这意味着如果读取超过0个字节,.reset()
将无法可靠地工作。
编辑: .mark()
标记了流中的当前位置。与C ++不同,您可以.seek()
文件的开头或结尾以及偏移量,Java流只允许您标记当前位置,然后使用.reset()
返回到它。这可以“回到开头”,但只有在处理开始之前标记它。
试试这个:
import java.io.*;
public class StreamTwice
{
public static void printLines(LineNumberReader r) throws IOException
{
String line;
while( (line = r.readLine()) != null )
System.out.println(line);
System.out.println();
}
public static void main(String []args) throws Exception
{
ByteArrayInputStream s = new ByteArrayInputStream(
"one\ntwo\nthree".getBytes()
);
LineNumberReader r = new LineNumberReader(new InputStreamReader(s));
r.mark(5000); // more than the number of bytes being read.
// this is the read ahead limit.
printLines(r);
r.reset(); // go back to where mark was called.
printLines(r);
}
}
尝试确保在调用.mark()
之前,不会读取比.reset()
中设置的预读限制更多的字节数。
P.S。 - 并非所有流(或读者)都支持.mark()
,您可以使用.markSupported()
进行检查。
答案 1 :(得分:0)
重置()将行阅读器重置为最新标记(如果按顺序执行,则为最后一个标记。)您需要做的是通过调用“reader.SetLineNumber(0);”参数手动更改行。表示您要转到的行号。