<p>根據JAVA官方文檔的描述mark(int readlimit)方法表示標記當前位置並保證在mark以後最多可以讀取readlimit字節<span class=t_tag tagphp?name=%CA%FD%BE%DD>數據</span>mark標記仍有效如果在mark後讀取超過readlimit字節數據mark標記就會失效調用reset()方法會有異常
但實際的運行情況卻和JAVA文檔中的描述並不完全相符 有時候在BufferedInputStream類中調用mark(int readlimit)方法後即使讀取超過readlimit字節的數據mark標記仍有效仍然能正確調用reset方法重置 </p><p>事實上mark在JAVA中的實現是和緩沖區相關的只要緩沖區夠大mark後讀取的數據沒有超出緩沖區的大小mark標記就不會失效如果不夠大mark後又讀取了大量的數據導致緩沖區更新原來標記的位置自然找不到了</p><p>因此mark後讀取多少字節才失效並不完全由readlimit參數確定也和BufferedInputStream類的緩沖區大小有關(默認情況下緩沖區大小為) 如果BufferedInputStream類的緩沖區大小大於readlimit在mark以後只有讀取超過緩沖區大小的數據mark標記才會失效看下面的例子 </p> view plain
view plain
view plain package packet
import javaioBufferedInputStream
import javaioByteArrayInputStream
import javaioIOException
/**
* @author WuDian
*
*/
public class MarkExample {
public static void main(String[] args) {
try {
// 初始化一個字節數組內有個字節的數據
byte[] bytes={}
// 用一個ByteArrayInputStream來讀取這個字節數組
ByteArrayInputStream in=new ByteArrayInputStream(bytes)
// 將ByteArrayInputStream包含在一個BufferedInputStream並初始化緩沖區大小為
BufferedInputStream bis=new BufferedInputStream(in)
// 讀取字節
Systemoutprint(bisread()+)
// 在字節處做標記同時設置readlimit參數為
// 根據JAVA文檔mark以後最多只能讀取個字節否則mark標記失效但實際運行結果不是這樣
Systemoutprintln(mark)
bismark()
/*
* 連續讀取兩個字節超過了readlimit的大小mark標記仍有效
*/
// 連續讀取兩個字節
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
// 調用reset方法未發生異常說明mark標記仍有效
// 因為雖然readlimit參數為但是這個BufferedInputStream類的緩沖區大小為
// 所以允許讀取字節
Systemoutprintln(reset)
bisreset()
/*
* 連續讀取個字節超過了緩沖區大小mark標記失效
* 在這個例子中BufferedInputStream類的緩沖區大小大於readlimit
* mark標記由緩沖區大小決定
*/
// reset重置後連續讀取個字節超過了BufferedInputStream類的緩沖區大小
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
// 再次調用reset重置拋出異常說明mark後讀取個字節mark標記失效
Systemoutprintln(reset again)
bisreset()
} catch (IOException e) {
// TODO Autogenerated catch block
eprintStackTrace()
}
}
}
運行結果如下
mark reset reset again javaioIOException Resetting to invalid mark at javaioBufferedInputStreamreset(BufferedInputStreamjava)
at packetMarkExamplemain(MarkExamplejava) 同樣的在調用mark(int readlimit)方法時如果readlimit大於BufferedInputStream類緩沖區的大小緩沖區會被擴大那mark後最多就可以讀readlimit字節
簡言之BufferedInputStream類調用mark(int readlimit)方法後讀取多少字節標記才失效是取readlimit和BufferedInputStream類的緩沖區大小兩者中的最大值而並非完全由readlimit確定這個在JAVA文檔中是沒有提到的
JAVA中mark()和reset()用法的通俗理解
mark就像書簽一樣在這個BufferedReader對應的buffer裡作個標記以後再調用reset時就可以再回到這個mark過的地方mark方法有個參數通過這個整型參數你告訴系統希望在讀出這麼多個字符之前這個mark保持有效讀過這麼多字符之後系統可以使mark不再有效而你不能覺得奇怪或怪罪它這跟buffer有關如果你需要很長的距離那麼系統就必須分配很大的buffer來保持你的mark //eg //reader is a BufferedReader
readermark()//要求在個字符之內這個mark應該保持有效系統會保證buffer至少可以存儲個字符int a = readerread()//讀了一個字符int b = readerread()//又讀了一個字符
//做了某些處理發現需要再讀一次readerreset()readerread()//讀到的字符和a相同readerread()//讀到的字符和b相同
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26119.html