Java中的IO流原理和流的分類詳解
Java IO流原理
1)I/O是input/Output的縮寫,I/O技術(shù)是非常實用的技術(shù),用于處理數(shù)據(jù)傳輸。如讀/寫文件,網(wǎng)絡(luò)通訊等;
2)Java程序中,對于數(shù)據(jù)的輸入和輸出操作以“流(stream)”的方式進行;
3)java.io包下提供了各種“流”類和接口,用以獲取不同種類的數(shù)據(jù),并通過方法輸入或輸出數(shù)據(jù);
4)輸入(input):讀取外部數(shù)據(jù)(磁盤、光盤等存儲設(shè)備的數(shù)據(jù)到程序(內(nèi)存)中);
5)輸出(output):將程序(內(nèi)存)數(shù)據(jù)輸出到磁盤、光盤等存儲設(shè)備中。
流的分類
1)按照操作數(shù)據(jù)單位不同分為:字節(jié)流(8bit),字符流(按字符)(分別按照字符和字節(jié)進行讀取,如果從操作單位方面看字符流操作效率較高,但是操作二進制文件時字節(jié)流不會出現(xiàn)錯誤,字節(jié)流操作文本文件比較好);
2)按數(shù)據(jù)流的流向不同分為:輸入流和輸出流;
3)按流的角色不同分為:節(jié)點流,處理流(包裝流);
(抽象基類) | 字節(jié)流 | 字符流 |
輸入流 | 字節(jié)輸入流的頂級父類 InputStream | 字符輸入流的頂級父類 Reader |
輸出流 | 字節(jié)輸出流的頂級父類 OutputStream | 字符輸出流的頂級父類 Writer |
- Java的IO流共涉及40多個類,都是從如上4個抽象基類派生的;
- 由這四個基類派生出來的子類名稱以其父類名作為子類名后綴;
InputStream抽象類實現(xiàn)了Closeable接口,Closeable接口上面還有一個AutoCloseable接口;OutputStream抽象類實現(xiàn)了Closeable接口和Flushable接口;Reader抽象類實現(xiàn)了Closeable接口和Readable接口;Writer抽象類實現(xiàn)了Appendable接口、Flushable接口和Closeable接口;在使用時,創(chuàng)建他們的實現(xiàn)子類。
InputStream常用子類
1)FileInputStream:文件輸入流;
2)BufferedInputStream:緩沖字節(jié)輸入流;
3)ObjectInputStream:對象字節(jié)輸入流;
package com.pero.inputStream; import org.junit.jupiter.api.Test; import java.io.FileInputStream; import java.io.IOException; /** * @author Pero * @version 1.0 */ public class FileInputStream_ { public static void main(String[] args) { } @Test //讀取文件 public void test(){ //定義文件路徑 String filePath = "d:\\demo\\test\\HelloWorld.txt"; //定義文件輸入流對象名稱 FileInputStream fileInputStream = null; //定義接收讀取一字節(jié)數(shù)據(jù) int readData; try { //獲取文件輸入流對象,用于讀取文件 fileInputStream = new FileInputStream(filePath); while ((readData = fileInputStream.read()) != -1){ //如果返回-1表示已經(jīng)讀取到最后一位 System.out.print((char)readData); //讀取數(shù)據(jù)為int型,需要轉(zhuǎn)成字符型char } } catch (IOException e) { throw new RuntimeException(e); }finally { //必須關(guān)閉流,釋放鏈接文件的流,否則造成資源浪費 try { fileInputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } } @Test public void test2(){ String path = "d:\\demo\\test\\HelloWorld.txt"; FileInputStream fileInputStream = null; byte[] bytes = new byte[8]; int readLength = 0; try { fileInputStream = new FileInputStream(path); //如果讀取正常返回讀取的字節(jié)數(shù) while((readLength = fileInputStream.read(bytes)) != -1){ //第一次讀取時,bytes第一次接收八個字符hello,wo; // 此時fileInputStream.read(bytes)返回值為8, //while循環(huán)不退出,輸出hello,wo后,再次進入循環(huán) // 第二次讀取bytes第二次接收rld! // 此時fileInputStream.read(bytes)返回值為4, // (bytes中存儲的為rld!o,wo,其中o,wo為上次讀取的數(shù)據(jù),bytes中沒有將其覆蓋) //但是new String(bytes, 0, readLength)輸出bytes數(shù)組的0~3(0~readLength-1)位的字符 //第三次讀取,讀取到數(shù)據(jù)的最后一位,此時fileInputStream.read(bytes)返回值為-1退出循環(huán) System.out.print(new String(bytes,0,readLength)); } } catch (IOException e) { throw new RuntimeException(e); }finally { try { fileInputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
OutputStream常用子類
1)FileOutputStream:文件輸出流。
package com.pero.outputStream_; import org.junit.jupiter.api.Test; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * @author Pero * @version 1.0 */ public class FileOutputStream_ { public static void main(String[] args) { } @Test public void writeFile(){ String path = "d:\\demo\\test\\next.txt"; FileOutputStream fileOutputStream = null; try { //fileOutputStream = new FileOutputStream(path);以此方式創(chuàng)建輸出流 //輸出文件內(nèi)容會覆蓋原來的內(nèi)容 //fileOutputStream = new FileOutputStream(path,true);以此方式創(chuàng)建輸出流 //輸出文件內(nèi)容會添加到原來的內(nèi)容之后 fileOutputStream = new FileOutputStream(path,true); //寫入一個字節(jié) //fileOutputStream.write('H'); //寫入字符串 String str = "Hello,world!"; //使用getBytes,將字符串轉(zhuǎn)成字節(jié)(byte)數(shù)組 fileOutputStream.write(str.getBytes()); //寫入字符串部分數(shù)據(jù)Hello(0~5-1) fileOutputStream.write(str.getBytes(),0,5); } catch (IOException e) { throw new RuntimeException(e); }finally { try { fileOutputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
文件拷貝(圖像)
package com.pero.outputStream_; import org.junit.jupiter.api.Test; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @author Pero * @version 1.0 */ public class FileCopy { public static void main(String[] args) { } @Test public void copy(){ //大文件讀取中,邊讀取數(shù)據(jù)邊輸出存放文件(流的形式) //將地址所在文件數(shù)據(jù)輸入到程序 //輸入、輸出路徑 String inputPath = "C:\\Users\\Pero\\Desktop\\4.jpeg"; //將文件數(shù)據(jù)輸出到指定地址存放 String outputPath = "D:\\demo\\test\\4.jpeg"; FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; byte[] bytes = new byte[1024]; //飽和讀取數(shù)量 int readLength = 0; try { fileInputStream = new FileInputStream(inputPath); fileOutputStream = new FileOutputStream(outputPath); //讀取文件數(shù)據(jù) while ((readLength = fileInputStream.read(bytes)) != -1){ //邊讀邊寫,一定要用write(bytes,0,readLength); //因為最后一次讀寫,不一定把bytes里的存儲數(shù)據(jù)完全覆蓋, //最后剩余的空間是倒數(shù)第二次傳輸?shù)牟糠謹?shù)據(jù),會發(fā)生錯誤 fileOutputStream.write(bytes,0,readLength); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (fileInputStream != null){ fileInputStream.close(); } if (fileOutputStream != null){ fileOutputStream.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
FileReader類和FileWriter類(字符流,按照字符來操作IO)
FileReader相關(guān)方法
1)構(gòu)造器:new FileReader(File/String)
2)read:每次讀取單個字符,則返回該字符,如果到了文件末尾則返回-1;
3)read(char[]):批量讀取多個字符到數(shù)組,返回讀取到的字符數(shù),如果到了文件末尾則返回-1;
相關(guān)API:
1)new String(char[] ):將char[]轉(zhuǎn)換阿成String;
2)new String(char[] ,off ,len):將char[]的指定部分轉(zhuǎn)換成String。
package com.pero.reader_; import org.junit.jupiter.api.Test; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /** * @author Pero * @version 1.0 */ public class FileReader_ { public static void main(String[] args) { } @Test public void reader(){ //創(chuàng)建路徑 String path = "d:\\demo\\test\\Story.txt"; FileReader fileReader = null; int data = 0; //char[] chars = new char[1024]; try { fileReader = new FileReader(path); //循環(huán)讀取 while ((data = fileReader.read()) != -1){ System.out.print((char)data); } } catch (IOException e) { throw new RuntimeException(e); }finally { try { if (fileReader != null){ fileReader.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } @Test public void reader1(){ String path = "d:\\demo\\test\\Story.txt"; char[] chars = new char[1024]; int length = 0; FileReader fileReader = null; try { fileReader = new FileReader(path); while ((length = fileReader.read(chars)) != -1){ System.out.print(new String(chars,0,length)); } } catch (IOException e) { throw new RuntimeException(e); }finally { try { if (fileReader != null){ fileReader.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
FileWriter相關(guān)方法
1)構(gòu)造器:new FileWriter(File/String):覆蓋模式,相當于流的指針在首端;
2)構(gòu)造器:new FileWriter(File/String,true):追加模式,相當于流的指針在尾端;
3)write(int ):寫入單個字符;
4)write(char[]):寫入指定數(shù)組;
5)write(char[],off,len):寫入指定數(shù)組的指定部分;
6)write(String):寫入整個字符串;
7)write(String,off,len):寫入字符串的指定部分。
相關(guān)API:String類中toCharArray:將String轉(zhuǎn)換成char[]。
注意:FileWriter使用后,必須要關(guān)閉(close)或刷新(flush),否則寫入不到指定的文件。
package com.pero.writer_; import org.junit.jupiter.api.Test; import java.io.FileWriter; import java.io.IOException; /** * @author Pero * @version 1.0 */ public class FileWriter_ { public static void main(String[] args) { } @Test public void writer(){ String path = "d:\\demo\\test\\note.txt"; FileWriter fileWriter = null; char[] chars = {'H','e','l','l','o',',','H','o','r','l','d','!'}; try { fileWriter = new FileWriter(path/*,true*/); fileWriter.write('h'); fileWriter.write(chars); fileWriter.write("不經(jīng)歷風(fēng)雨,怎能見彩虹"); fileWriter.write("鋤禾日當午,汗滴禾下土",0,5); fileWriter.write(chars,0,5); } catch (IOException e) { throw new RuntimeException(e); }finally { try { fileWriter.close(); //fileWriter.flush(); } catch (IOException e) { throw new RuntimeException(e); } } } }
到此這篇關(guān)于Java中的IO流原理和流的分類詳解的文章就介紹到這了,更多相關(guān)Java的IO流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JDK17在Windows安裝及環(huán)境變量配置超詳細的教程
這篇文章主要介紹了JDK17在Windows安裝及環(huán)境變量配置超詳細的教程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-11-11淺談java.util.concurrent包中的線程池和消息隊列
這篇文章主要介紹了淺談java.util.concurrent包中的線程池和消息隊列,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Mybatis如何使用動態(tài)語句實現(xiàn)批量刪除(delete結(jié)合foreach)
這篇文章主要介紹了Mybatis如何使用動態(tài)語句實現(xiàn)批量刪除(delete結(jié)合foreach),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03深入淺析ArrayList 和 LinkedList的執(zhí)行效率比較
這篇文章主要介紹了ArrayList 和 LinkedList的執(zhí)行效率比較的相關(guān)資料,需要的朋友可以參考下2017-08-08springboot構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢的方法
本文主要介紹了springboot怎樣構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11SpringBoot+MybatisPlus+Mysql+JSP實戰(zhàn)
這篇文章主要介紹了SpringBoot+MybatisPlus+Mysql+JSP實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12