我是Java流的新手,我想阅读特定的文件内容,然后需要从头开始阅读。我创建了一个BufferedInputStream,我对BufferedInputStream.mark(int markLimit)的文档感到困惑
文档说:
public void mark(int readlimit)
此方法通过调用reset()方法在输入中标记流可以“重置”的位置。参数readlimit是在标记变为无效之前设置标记后可从流中读取的字节数。例如,如果调用mark()时读取限制为10,那么在调用reset()方法之前从流中读取11个字节的数据时,标记无效,并且不需要流对象实例记得那个标记。
请注意,此方法可以记住的字节数可能大于内部读缓冲区的大小。它也不依赖于支持标记/重置功能的从属流。
覆盖: 在类FilterInputStream中标记
参数: readlimit - 标记变为无效之前可以读取的字节数**
我的代码是:
public class Test {
public static void main(String[] args) throws IOException {
File resource = new File("beforeFix.txt");
FileInputStream fileInputStream = new FileInputStream(resource);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
int i = bufferedInputStream.read();
bufferedInputStream.mark(1);
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
bufferedInputStream.reset();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
i = bufferedInputStream.read();
bufferedInputStream.reset();
}
}
在上面的代码中,我将marklimit设置为1,但根据文档标记不会变为无效。
任何人都可以清楚地解释一下用小例子设置这个的实际目的是什么?
提前致谢
答案 0 :(得分:1)
为了使重置工作并返回到您标记的位置,标记后读取的数据需要在内存中缓冲。标记时指定的值是应为此保留的内存量。
因此,如果您打算在调用reset之前读取100个字节,那么您的缓冲区需要至少100个字节,这就是您必须使用的标记。
fb.orderByChild("Lastname").equalTo('hoo').once("child_added", function(snapshot){
console.log(snapshot.ref());
console.log(snapshot.val());
// var snapref = snapshot.ref();
snapshot.ref().update({
FirstName: 'yoyo1'
});
})
<强>更新强>
bufferedInputStream.mark(200);
... read no more than 200 bytes ...
bufferedInputStream.reset(); // reset back to marked position
的文档看起来与实际行为不符。文档说明:
mark
然而,它看起来应该是the maximum limit of bytes that can be read before the mark position becomes invalid
,或者至少如果它们仍然支持重置到标记位置,则一旦超出读取限制就不需要丢弃标记的基础实现
答案 1 :(得分:1)
通过使用指定限制调用mark
,您要求在读取到指定限制后支持重置的功能,您不会拒绝超出该限制的功能。 The specification清楚地说:
但是,如果在调用
readlimit
之前从流中读取的reset
个字节超过BufferedInputStream
,则根本不需要记住任何数据。
“不要求”不暗示“不允许”。规范简单地陈述了你不能期望永远工作的东西,它没有陈述你总是会失败的东西。
在BufferedInputStream
的情况下,很容易解释在幕后发生的事情。每个File resource = new File("beforeFix.txt");
FileInputStream fileInputStream = new FileInputStream(resource);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 1);
int i = bufferedInputStream.read();
bufferedInputStream.mark(1);
i = bufferedInputStream.read();
i = bufferedInputStream.read();
bufferedInputStream.reset(); // will fail
都有一个容量,default是8192,并且它总是可以重置超过其当前缓冲区容量的字节数。通过指定更高的限制,您将使其在需要时分配更大的缓冲区,以实现保证。
由于您无法查询流的当前缓冲区容量,因此只要您没有读取超过指定限制的字节数,就只能依赖重置的保证。
很容易更改您的示例以使其无法重现:
f(r,sigma,epsilon)=4*epsilon*((sigma/r)**12-(sigma/r)**6)
sigma=2.6
epsilon=5
set arrow 1 from first 3,0 to first 3, f(3,sigma,epsilon)
set arrow 2 from first 3,0 to first 2.8, f(2.8,sigma,epsilon)
set label 1 "(r_0, {/Symbol e}_0)" at first 3,0 center offset 0,1
set xlabel "Distance r_0 ({\305})"
set ylabel "Energy E (J/mol)
set xr [2:5.2]
set yr [-6:12]
set key reverse Left at 4,5
plot for [epsi= epsilon-1:epsilon+1:1 ] f(x,sigma,epsi) title sprintf("12-6 LJ {/Symbol s}=%.1f {/Symbol e}=%.1f",sigma,epsi)
set term pngcairo enhanced
set out "LJ.png"
replot
答案 2 :(得分:0)
请阅读以下文档以更好地理解它。我和您有同样的疑问,然后决定详细阅读它。
从第一点开始,现在非常清楚,不能保证会抛出IOException。因此,如果在调用mark方法后读取的字节数超出了允许的字节数(mark方法的指定参数),则此操作很冒险,因此不建议这样做。
从第二点开始,您可以了解如果不抛出IOException会发生什么。
文档链接:https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#reset--
答案 3 :(得分:0)
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
static final String fileAbsolutePath = "file.txt";
public static void main(String[] args) {
// file contains 3 chars 'a', 'b', and 'c'
try (FileInputStream fileInputStream = new FileInputStream(fileAbsolutePath);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)) {
System.out.println((char) bufferedInputStream.read()); // prints a
bufferedInputStream.mark(2); // place mark at second byte
System.out.println((char) bufferedInputStream.read()); // prints b
System.out.println((char) bufferedInputStream.read()); // prints c
System.out.println(bufferedInputStream.read()); // prints -1
bufferedInputStream.reset(); // meaning start again from where I placed the mark
System.out.println((char) bufferedInputStream.read()); // prints b
System.out.println((char) bufferedInputStream.read()); // prints c
System.out.println( bufferedInputStream.read()); // prints -1
} catch (IOException ie) { ie.printStackTrace();}
}
}