linux系統(tǒng)中InputStream輸入流的方法之reset()和mark()命令的注意事項

今天寫一個讀寫程序,運用到InputStream的reset方法是發(fā)現(xiàn)竟然失敗了,然后查了一下JDK源碼,發(fā)現(xiàn)BufferInputStream重寫了父類FilterInputStream的mark和resetf方法,其有支持 mark 和 reset 方法的能力。而FileInputStream則沒有重寫父類InputStream的這兩個方法,其不具有mark和reset方法的能力。
在JDK源碼中,寫到public synchronized void mark(int readlimit)在該輸入流中標記當(dāng)前位置。 后續(xù)調(diào)用 reset 方法重新將流定位于最后標記位置,以便后續(xù)讀取能重新讀取相同字節(jié)。
readlimit 參數(shù)給出當(dāng)前輸入流在標記位置變?yōu)榉欠ㄇ霸试S讀取的字節(jié)數(shù)。
這句話的意思是說:mark就像書簽一樣,用于標記,以后再調(diào)用reset時就可以再回到這個mark過的地方。mark方法有個參數(shù),通過這個整型參數(shù),你告訴系統(tǒng),希望在讀出這么多個字符之前,這個mark保持有效。比如說mark(10),那么在read()10個以內(nèi)的字符時,reset()操作后可以重新讀取已經(jīng)讀出的數(shù)據(jù),如果已經(jīng)讀取的數(shù)據(jù)超過10個,那reset()操作后,就不能正確讀取以前的數(shù)據(jù)了,因為此時mark標記已經(jīng)失效。
下面是BufferInputStream以及父類FilterInputStream 中這兩個方法的默認實現(xiàn)//FilterInputStream.java
public synchronized void mark(int readlimit) {in.mark(readlimit);
}
public synchronized void reset() throws IOException {in.reset();
}
<br>public boolean markSupported() {<br> return in.markSupported()<br>}
//BufferedInputStream.java
public synchronized void mark(int readlimit) {marklimit = readlimit;
markpos = pos;
}
public synchronized void reset() throws IOException {getBufIfOpen(); // Cause exception if closedif (markpos < 0)
throw new IOException("Resetting to invalid mark");pos = markpos;
}<br><br>
public boolean markSupported() {
return true;
} //支持mark操作
而FileInputStream沒有重寫父類InputStream的默認實現(xiàn),其默認實現(xiàn)如下:
//InputStream.java
public synchronized void mark(int readlimit) {}//空實現(xiàn)什么都沒有實現(xiàn)public synchronized void reset() throws IOException {throw new IOException("mark/reset not supported");}//不支持reset操作
public boolean markSupported() {
return false;
} //不支持mark操作
下面是一個簡單的程序,用于設(shè)置reset和mark.
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class TestInputStream {
public void read(InputStream in) throws IOException {if(in == null) {
return;
}
int len=0;
in.mark(1);
in.read() //第一次讀取
in.reset();//又可以重新讀取
in.read()//第二次讀取跟第一次讀取結(jié)果一樣。因為只讀了一個,沒有超過mark設(shè)置的整數(shù)。所以mark有效}
public static void main(String[] args) throws IOException {TestInputStream test = new TestInputStream();String fileName = "F:/Google.txt";
InputStream in1 = new FileInputStream(new File(fileName));if(!in1.markSupported()) {
in1 = new BufferedInputStream(in1);
}
test.read(in1);
byte[] buf = new byte[100];
while(in1.read(buf, 0, buf.length)!=-1) {System.out.println(buf);
}
System.out.println("Success!");
}
}
總結(jié):
mark
public void mark(int readlimit)
mark 的常規(guī)協(xié)定是:如果方法 markSupported 返回 true,那么輸入流總是在調(diào)用 mark 之后記錄所有讀取的字節(jié),并時刻準備在調(diào)用方法 reset 時(無論何時),再次提供這些相同的字節(jié)。但是,如果在調(diào)用 reset 之前可以從流中讀取多于 readlimit 的字節(jié),則不需要該流記錄任何數(shù)據(jù)。
參數(shù):
readlimit - 在標記位置失效前可以讀取字節(jié)的最大限制。
4 reset
public void reset() throws IOException
將此流重新定位到最后一次對此輸入流調(diào)用 mark 方法時的位置。
reset 的常規(guī)協(xié)定是:
1、如果方法 markSupported 返回 true,那么:
如果創(chuàng)建流以后未調(diào)用方法 mark,或最后調(diào)用 mark 以后從該流讀取的字節(jié)數(shù)大于最后調(diào)用 mark 時的參數(shù),則可能拋出 IOException。
如果未拋出這樣的 IOException,則將該流重新設(shè)置為這種狀態(tài):最近一次調(diào)用 mark 以后(如果未調(diào)用過 mark,則從文件開頭開始)讀取的所有字節(jié)將重新提供給 read 方法的后續(xù)調(diào)用者,后跟任何從調(diào)用 reset 時起將作為下一輸入數(shù)據(jù)的字節(jié)。
2、如果方法 markSupported 返回 false,那么:
對 reset 的調(diào)用可能拋出 IOException。
如果未拋出 IOException,則將該流重新設(shè)置為一種固定狀態(tài),該狀態(tài)取決于輸入流的特定類型及其創(chuàng)建方式。提供給 read 方法后續(xù)調(diào)用者的字節(jié)取決于特定類型的輸入流。
除了拋出 IOException 之外,類 InputStream 的方法 reset 不執(zhí)行任何操作。
拋出:
IOException - 如果未標記此流或該標記失效。
以上就是在linux系統(tǒng)中InputStream輸入流的方法的注意事項,謝謝閱讀,希望能幫到大家,請繼續(xù)關(guān)注腳本之家,我們會努力分享更多優(yōu)秀的文章。
相關(guān)文章
Fedora Linux 42 穩(wěn)定版發(fā)布: 帶來大量新功能和軟件更新
Fedora 42昨日發(fā)布,這是 Red Hat 贊助開發(fā)的杰出前沿 Linux 發(fā)行版的最新版,包含大量新功能和軟件更新,使其成為 2025 年上半年發(fā)布的一款出色的 Linux 操作系統(tǒng)之一,內(nèi)2025-04-16如何在Linux查看硬盤信息? 查看Linux硬盤大小類型和硬件信息的5種方法
使用Linux系統(tǒng)的過程中,查看和了解硬盤信息是非常重要的工作,尤其是對于系統(tǒng)管理員而言,那么在Linux系統(tǒng)中如何查看硬盤信息?以下是具體內(nèi)容介紹2025-03-12如何在 Linux 中查看 CPU 詳細信息? 3招輕松查看CPU型號、核心數(shù)和溫度
在日常運維工作中,獲取 CPU 信息是系統(tǒng)運維管理員常見的工作內(nèi)容,無論是為了性能調(diào)優(yōu)、硬件升級還是僅僅滿足好奇心2025-03-11什么是 Arch Linux? 獨樹一幟的Arch Linux發(fā)行版分析
Arch Linux是為簡化,優(yōu)化,現(xiàn)代化,實用主義,用戶中心和多功能性而創(chuàng)建Linux發(fā)行版,究竟是什么讓 Arch 與眾不同?下面我們就來簡要解讀2025-02-19如何在Linux環(huán)境下制作 Win11裝機U盤?
一直用的linux辦公,想要將筆記本電腦從 Linux 系統(tǒng)切換回 Windows 11,我們可以制作一個win11裝機u盤,詳細如下2025-02-17Rsnapshot怎么用? 基于Rsync的強大Linux備份工具使用指南
Rsnapshot 不僅可以備份本地文件,還能通過 SSH 備份遠程文件,接下來詳細介紹如何安裝、配置和使用 Rsnapshot,包括創(chuàng)建每小時、每天、每周和每月的本地備份,以及如何進2025-02-06Linux Kernel 6.13發(fā)布:附更新內(nèi)容及新特性解讀
Linux 內(nèi)核 6.13 正式發(fā)布,新版本引入了惰性搶占支持,簡化內(nèi)核搶占邏輯,通過減少與調(diào)度器相關(guān)的調(diào)用次數(shù),讓內(nèi)核在運行時表現(xiàn)更優(yōu),從而提高效率2025-01-23五大特性引領(lǐng)創(chuàng)新! 深度操作系統(tǒng) deepin 25 Preview預(yù)覽版發(fā)布
今日,深度操作系統(tǒng)正式推出deepin 25 Preview版本,該版本集成了五大核心特性:磐石系統(tǒng)、全新DDE、Treeland窗口合成器、AI For OS以及Distrobox子系統(tǒng)2025-01-18Linux Mint Xia 22.1重磅發(fā)布: 重要更新一覽
Beta 版 Linux Mint“Xia” 22.1 發(fā)布,新版本基于 Ubuntu 24.04,內(nèi)核版本為 Linux 6.8,這次更新帶來了諸多優(yōu)化和改進,進一步鞏固了 Mint 在 Linux 桌面操作系統(tǒng)領(lǐng)域的2025-01-16LinuxMint怎么安裝? Linux Mint22下載安裝圖文教程
Linux Mint22發(fā)布以后,有很多新功能,很多朋友想要下載并安裝,該怎么操作呢?下面我們就來看看詳細安裝指南2025-01-16