一、寫在開頭 在計算機(jī)領(lǐng)域中百分之九十以上的程序擁有著和外部設(shè)備交互的功能,這就是我們常說的IO(Input/Output:輸入/輸出),所謂輸入就是外部數(shù)據(jù)導(dǎo)入計算機(jī)內(nèi)存中的過程,輸出則是將內(nèi)存或者說程序中的數(shù)據(jù)導(dǎo)入到外部存儲中,如數(shù)據(jù)庫、文件以及其他本地磁盤等。 二、什么是IO流 這種輸入輸出往
在計算機(jī)領(lǐng)域中百分之九十以上的程序擁有著和外部設(shè)備交互的功能,這就是我們常說的IO(Input/Output:輸入/輸出),所謂輸入就是外部數(shù)據(jù)導(dǎo)入計算機(jī)內(nèi)存中的過程,輸出則是將內(nèi)存或者說程序中的數(shù)據(jù)導(dǎo)入到外部存儲中,如數(shù)據(jù)庫、文件以及其他本地磁盤等。
這種輸入輸出往往遵循著先入先出,順序存取的特點,像水流一般,因此我們稱這樣的操作為流(Stream),如下我們根據(jù)不同的標(biāo)準(zhǔn),將IO流分為幾個門類:
根據(jù)數(shù)據(jù)流向:
根據(jù)處理單位:
根據(jù)功能點:
在java.io包中多達(dá)40多個類,它們的基類來源于InputStream、OutputStream、Reader、Writer這四個,我們一一看過。
InputStream作為所有字節(jié)輸入流的父類,主要作用是將外部數(shù)據(jù)讀取到內(nèi)存中,主要方法如下(JDK8):
我們使用FileInputStream(文件字節(jié)輸入流)進(jìn)行如上方法的使用測試:
public class Test {
public static void main(String[] args) throws IOException {
try (InputStream fis = new FileInputStream("E:\\input.txt")) {
System.out.println("可讀取字節(jié)數(shù):"
+ fis.available());
int content;
long skip = fis.skip(3);
System.out.println("忽略字節(jié)數(shù):" + skip);
System.out.print("剩余全量字節(jié):");
while ((content = fis.read()) != -1) {
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
輸出:
可讀取字節(jié)數(shù):20
忽略字節(jié)數(shù):3
剩余全量字節(jié):name is JavaBuild
outputstream作為所有字節(jié)輸出流的父類,主要則是將內(nèi)存或者說程序中的數(shù)據(jù)以字節(jié)流的方式導(dǎo)入到外部存儲中,如數(shù)據(jù)庫、文件以及其他本地磁盤等。它的使用方法相比較字節(jié)輸入流要少:
我們同樣以FileOutputStream為例進(jìn)行上述方法的測試:
public class Test {
public static void main(String[] args) throws IOException {
try (FileOutputStream output = new FileOutputStream("E://output.txt")) {
byte[] array = "JavaBuild".getBytes();
//將一個字節(jié)數(shù)組寫入本地E盤的外部文件output.txt中
output.write(array);
//換行方式1:Windows下的換行符為"\r\n"
output.write("\r\n".getBytes());
//換行方式2:推薦使用,具有良好的跨平臺性
String newLine = System.getProperty("line.separator");
output.write(newLine.getBytes());
//輸出字節(jié),這里的數(shù)字會被轉(zhuǎn)為asicc碼中對應(yīng)的字符
output.write(64);
output.write(56);
output.write(56);
output.write(56);
//關(guān)閉輸出流
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
效果:
這里可以直接輸出單字節(jié)數(shù)據(jù),也可以輸出指定的字節(jié)數(shù)組。輸出字節(jié)時以int類型輸出,最終根據(jù)ASCII表轉(zhuǎn)為字符。如十進(jìn)制64的轉(zhuǎn)為@符號。
在講解字符流之前,我們來解釋一個面試問題:
“為什么有了字節(jié)流了還需要使用更耗時的字符流”
確實,字節(jié)作為信息存儲的最小單元,我們可以通過字節(jié)流實現(xiàn)所有信息的輸入與輸出,但有時候會存在一些問題,比如中文輸入時的編碼問題,將上述3.1中的測試代碼稍微改一下,執(zhí)行結(jié)果如下,中文在控制臺輸出時亂碼了。當(dāng)然我們可以通過設(shè)置編碼來規(guī)避這個問題,但有時候不曉得編碼時,亂碼真的會帶來潛在風(fēng)險!
字符流與字節(jié)流的區(qū)別:
說了這么多,我們現(xiàn)在來看一下Reader這個字符輸入流提供的主要方法吧,其實和InputStream差不多,只不過一個是以字節(jié)為單位的讀取,一個是以字符為單位。
我們將上述3.1中的測試代碼稍作加工,采用FileReader流進(jìn)行輸入,打印結(jié)果:
可以看到即便有中文,輸出在控制臺也沒有亂碼,因為字符流默認(rèn)采用的是 Unicode 編碼。
那么字符流是如何實現(xiàn)txt文件讀取的呢?通過FileReader類的繼承關(guān)系我們可以看到它繼承了InputStreamReader,這是一個字節(jié)轉(zhuǎn)字符輸入流,所以說從根本上,字符流底層依賴的還是字節(jié)流!
// 字節(jié)流轉(zhuǎn)換為字符流的橋梁
public class InputStreamReader extends Reader {
}
// 用于讀取字符文件
public class FileReader extends InputStreamReader {
}
writer是將內(nèi)存或者說程序中的數(shù)據(jù)以字符流的方式導(dǎo)入到外部存儲中,如數(shù)據(jù)庫、文件以及其他本地磁盤等。
常用方法也和OutputStream相似:
我們同樣以FileWriter為例,去測試一下:
public class Test {
public static void main(String[] args) throws IOException {
try (FileWriter fw = new FileWriter("E:\\outwriter.txt")) {
fw.write("大家好。!");
fw.append("我是JavaBuild");
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果本篇博客對您有一定的幫助,大家記得
留言+點贊+收藏
呀。原創(chuàng)不易,轉(zhuǎn)載請聯(lián)系Build哥!
如果您想與Build哥的關(guān)系更近一步,還可以關(guān)注“JavaBuild888”,在這里除了看到《Java成長計劃》系列博文,還有提升工作效率的小筆記、讀書心得、大廠面經(jīng)、人生感悟等等,歡迎您的加入!
機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實現(xiàn)對象集合與DataTable的相互轉(zhuǎn)換
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動態(tài)代理的對比分析
閱讀Win11筆記本“自動管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)