IO的简介
IO
IO簡(jiǎn)介
In/Out: 相對(duì)于程序而言的輸入(讀取)和輸出(寫出)的過(guò)程。
即: 通過(guò)java程序到磁盤讀取數(shù)據(jù)的過(guò)程, 我們稱為In的過(guò)程, 也就是讀取(輸入)
將java程序中的數(shù)據(jù)寫入磁盤的過(guò)程, 我們稱為Out的過(guò)程, 也就是寫出(輸出)
在Java中,根據(jù)處理的數(shù)據(jù)單位不同,分為字節(jié)流和字符流。
字節(jié)流: 一個(gè)字節(jié)(byte)一個(gè)字節(jié)的去讀取, 或者寫出
字符流: 一個(gè)字符一個(gè)字符的去讀取, 或者寫出
JDK核心類庫(kù)中提供了IO流相關(guān)的類, 這些類都在<java.io>包下
流的概念
程序中數(shù)據(jù)的讀取和寫入, 可以想象成水流在管道中流動(dòng)。
– 流只能單方向流動(dòng)
– 輸入流用來(lái)讀取in
– 輸出流用來(lái)寫出Out
– 數(shù)據(jù)只能從頭到尾順序的讀取一次或?qū)懗鲆淮?/p>
節(jié)點(diǎn)流和處理流
按照流是否直接與特定的地方(如磁盤,內(nèi)存,設(shè)備等)相連,分為節(jié)點(diǎn)流和處理流兩類
節(jié)點(diǎn)流
可以從或向一個(gè)特定的地方(節(jié)點(diǎn))讀寫數(shù)據(jù)
處理流
是對(duì)一個(gè)已存在的流的連接和封裝,通過(guò)所封裝的流的功能調(diào)用實(shí)現(xiàn)數(shù)據(jù)讀寫
處理流特點(diǎn)
處理流的構(gòu)造方法總是要帶一個(gè)其他的流對(duì)象做參數(shù),一個(gè)流對(duì)象經(jīng)過(guò)其他流的多次包裝,成為流的鏈接.
通常節(jié)點(diǎn)流也被稱之為低級(jí)流.處理流也被稱之為高級(jí)流或者過(guò)濾流
節(jié)點(diǎn)流
OutputStream抽象類
此抽象類是表示輸出字節(jié)流的所有類的超類。輸出流接受輸出字節(jié)并將這些字節(jié)發(fā)送到某個(gè)接收器。
FileOutputStream字節(jié)輸出流
直接插在文件上,直接寫出文件數(shù)據(jù)
創(chuàng)建對(duì)象:
FileOutputStream(String name) ? 創(chuàng)建一個(gè)向具有指定名稱的文件中寫入數(shù)據(jù)的輸出文件流。 FileOutputStream(File file) ? 創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫入數(shù)據(jù)的文件輸出流。 FileOutputStream(File file, boolean append) –追加 ? 創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫入數(shù)據(jù)的文件輸出流。注意: 以上構(gòu)造方法中, 如果參數(shù)指向的文件以及父目錄都不存在, 將會(huì)拋出FileNotFoundException異常!
如果參數(shù)指向的文件不存在, 但文件的所在目錄存在, 將不會(huì)拋異常, 程序會(huì)自動(dòng)創(chuàng)建該文件!
FileOutputStream代碼案例
package io;import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream;/*** FOS FileOutputStream 文件輸出流*/ public class FOSDemo {public static void main(String[] args) throws Exception {//1.創(chuàng)建一個(gè)FileOutputStream流,將數(shù)據(jù)輸出到./test.dat文件中//File file = new File("./test.dat");//如果沒(méi)有該文件,會(huì)自動(dòng)創(chuàng)建文件//true 表示開(kāi)啟流的追加模式,就不會(huì)覆蓋原有的內(nèi)容了//默認(rèn)是false,是覆蓋模式OutputStream out =new FileOutputStream("./test.dat",true);//2.開(kāi)始向文件寫入數(shù)據(jù)//write寫出一個(gè)字節(jié)//此處寫入的是一個(gè)int,int占4字節(jié)// x x x x//1個(gè)字節(jié)等于8個(gè)二進(jìn)制位//0 1 10 11 100//00000000 00000000 00000000 00000001//00000000 00000000 00000001 00000001out.write(1);//00000001out.write(97);//aout.write(98);//bout.write(99);//cout.write(100);//dout.write(255);out.write(257);//1//write寫一個(gè)byte數(shù)組//getBytes將字符串轉(zhuǎn)成字節(jié)數(shù)組out.write("ABCDE".getBytes());//輸出byte數(shù)組的一部分 表示從下標(biāo)1處(G)開(kāi)始,輸出后面的3個(gè)字節(jié)(包括G,GHI)//out.write("FGHIJ".getBytes(),1,3);//3.關(guān)閉流(釋放資源)System.out.println("成功的將數(shù)據(jù)寫入到了test.dat中");out.close();} }InputStream抽象類
此抽象類是表示字節(jié)輸入流的所有類的超類/抽象類。
FileInputStream子類
直接插在文件上,直接讀取文件數(shù)據(jù)。
創(chuàng)建對(duì)象
FileInputStream(File file)
? 通過(guò)打開(kāi)一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè) FileInputStream,該文件通過(guò)文件系統(tǒng)中的 File 對(duì)象 file 指定。
FileInputStream(String pathname)
? 通過(guò)打開(kāi)一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè) FileInputStream,該文件通過(guò)文件系統(tǒng)中的路徑名 name 指定。
FileInputStream代碼案例
package io;import java.io.FileInputStream; import java.io.InputStream;/*** FIS FileInputStream 文件輸入流*/ public class FISDemo {public static void main(String[] args) throws Exception {//File file = new File("./test.dat");//FileInputStream in = new FileInputStream(file);InputStream in =new FileInputStream("./test.dat");/*int read() 讀取文件中的1個(gè)字節(jié),返回該字節(jié)的整數(shù)形式是將讀取到的字節(jié)的2進(jìn)制保存在返回的int值的最后8位上對(duì)于我們來(lái)說(shuō)test.dat文件的二進(jìn)制形式如下01100001 01100010 01100011^^^^^^^^0110000100000000 00000000 00000000 01100001轉(zhuǎn)成int值 97如果返回的整數(shù)是-1,表示讀到了流的末尾-1的2進(jìn)制:11111111 11111111 11111111 11111111寫入-1,只取最后8位 11111111 255讀取的時(shí)候,1111111100000000 00000000 00000000 11111111*/ // System.out.println(in.read());//a // System.out.println(in.read());//b // System.out.println(in.read());//c // System.out.println(in.read());//d // System.out.println(in.read());//e // System.out.println(in.read());//f // System.out.println(in.read());//g // System.out.println(in.read());//h // System.out.println(in.read());//-1 表示沒(méi)有內(nèi)容啦//重復(fù)的讀取可以利用循環(huán)來(lái)完成/*for循環(huán)一般用于控制次數(shù)的循環(huán)while循環(huán)一般用于不知道次數(shù)的循環(huán)*///定義變量,用于存儲(chǔ)每次從文件中讀取的數(shù)據(jù)(1個(gè)字節(jié))int data;while ((data = in.read())!=-1){System.out.println(data);}//關(guān)閉流in.close();} }復(fù)制文件
復(fù)制文件代碼案例
package io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream;/*** 復(fù)制文件*/ public class CopyDemo {public static void main(String[] args) throws Exception {//1.創(chuàng)建讀取要復(fù)制的文件的流FileInputStream fis =new FileInputStream("./DAY02/demo.jpg");//2.創(chuàng)建輸入要?jiǎng)?chuàng)建的目標(biāo)文件FileOutputStream fos =new FileOutputStream("./DAY02/demo_cp.jpg");long start = System.currentTimeMillis();//3.利用輸入流,將demo.jpg的字節(jié)讀取到內(nèi)存中int data;while ((data=fis.read())!=-1){//4.每讀取一個(gè)字節(jié),要將字節(jié)寫入到目標(biāo)文件中fos.write(data);}long end = System.currentTimeMillis();System.out.println("復(fù)制完畢,共花費(fèi)了:"+(end-start)+"ms");//16882ms//5.關(guān)閉流fis.close();fos.close();} }快讀寫優(yōu)化代碼案例
package io;import java.io.FileInputStream; import java.io.FileOutputStream;/*** 復(fù)制文件* 提高每次讀寫的數(shù)據(jù)量,減少實(shí)際讀寫的次數(shù),可以提高讀寫的效率* 一組字節(jié)一組字節(jié)的讀寫:塊讀寫形式*/ public class CopyDemo2 {public static void main(String[] args) throws Exception {//1.創(chuàng)建讀取要復(fù)制的文件的流FileInputStream fis =new FileInputStream("./DAY02/demo.jpg");//2.創(chuàng)建輸入要?jiǎng)?chuàng)建的目標(biāo)文件FileOutputStream fos =new FileOutputStream("./DAY02/demo_cp.jpg");/*1.簡(jiǎn)單介紹實(shí)現(xiàn)思路超類:java.io.inputStram中定義了塊讀取字節(jié)的方法int read(byte[] data) 一次性讀取給定的字節(jié)數(shù)組總長(zhǎng)度的字節(jié)量,并存入到該數(shù)組中返回值為實(shí)際的字節(jié)量,如果返回的是-1,表示流讀到了末尾1)假定文件只有7個(gè)字節(jié),然后四個(gè)字節(jié)一讀取demo.jpg文件數(shù)據(jù)10101001 10101000 10101010 01010100 10101010 10101011 10101010byte[] data = new byte[4]; 定義4個(gè)字節(jié)數(shù)組int len; 返回讀取的字節(jié)數(shù)量2)第一次調(diào)用方法讀取4個(gè)字節(jié)len = fis.read(data);demo.jpg文件數(shù)據(jù)10101001 10101000 10101010 01010100 10101010 10101011 10101010^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^data:[10101001 10101000 10101010 01010100]len: 4 表示此次讀到了4個(gè)字節(jié)3)第二次調(diào)用方法讀取剩余的字節(jié),但是此時(shí)只剩三個(gè)demo.jpg文件數(shù)據(jù)10101001 10101000 10101010 01010100 10101010 10101011 10101010^^^^^^^^ ^^^^^^^^ ^^^^^^^^data:[10101010 10101011 10101010 01010100]|----本次讀取到的數(shù)據(jù)--------||-舊數(shù)據(jù)-|len:34)第三次調(diào)用方法,讀取字節(jié)demo.jpg文件數(shù)據(jù)10101001 10101000 10101010 01010100 10101010 10101011 10101010 文件末尾^^^^^^^data:[10101010 10101011 10101010 01010100]|--------------舊數(shù)據(jù)----------------|len:-1 表示文件末尾了*///3.利用輸入流,將demo.jpg的字節(jié)讀取到內(nèi)存中/*0 1 1位2進(jìn)制 1bit0000000 8位2進(jìn)制稱為1byte(1字節(jié))1024byte=1kb1024kb=1mb1024mb=1gb1024gb=1t*/byte[] data = new byte[1024*10];//10kbint len;long start = System.currentTimeMillis();while ((len = fis.read(data))!=-1){//fos.write(data);fos.write(data,0,len);}long end = System.currentTimeMillis();System.out.println("復(fù)制完畢,共花費(fèi)了:"+(end-start)+"ms");//3ms//5.關(guān)閉流fis.close();fos.close();} }寫入字符串
package io;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.charset.StandardCharsets;/*** 向文件寫出字符串*/ public class WriterStringDemo {public static void main(String[] args) throws Exception {//向demo.txt文件寫入字符串FileOutputStream fos =new FileOutputStream("./DAY02/demo.txt");String line = "bi,bi,im' sheep~bi,bi,im' sheep~";/*String提供了將字符串轉(zhuǎn)換為字節(jié)數(shù)組的方法,通常使用UTF-8字符集getBytes()方法添加如下的參數(shù)java.nio.charset.StandardCharsets指定編碼位UTF_8*/fos.write(line.getBytes(StandardCharsets.UTF_8));fos.write("比,比,安慕希~比,比,安慕希~".getBytes(StandardCharsets.UTF_8));fos.close();} }簡(jiǎn)易筆記本
package io;import javax.sound.sampled.Line; import javax.swing.text.html.StyleSheet; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.charset.StandardCharsets; import java.util.Scanner;/*** @author少珩* @data 2022/3/7 20:11* 實(shí)現(xiàn)簡(jiǎn)易的記事本工具* 程序啟動(dòng)后,要求將控制臺(tái)輸入的每一行的字符串都寫入到文件note.txt中,* 當(dāng)在控制臺(tái)輸入exit時(shí),程序退出*/ public class TestNotes {public static void main(String[] args) throws Exception {System.out.println("請(qǐng)開(kāi)始輸入內(nèi)容,單獨(dú)輸入exit退出");FileOutputStream fos = new FileOutputStream("./DAY02/note.txt");Scanner scanner = new Scanner(System.in);//構(gòu)建一個(gè)死循環(huán)//for(;;) for循環(huán)的死循環(huán)while (true) {//每次循環(huán)都接受在控制臺(tái)輸入的一句字符串String line = scanner.nextLine();//先判斷l(xiāng)ine是否是exit,如果是,停止錄入//String類中已經(jīng)幫我們重寫了equals方法/*不建議比較字符串相等時(shí)這樣寫 對(duì)象.equals(字符串)line.equals("exit")line都是用戶傳遞過(guò)來(lái)的,我們不能控制用戶輸入的是否為空*///if("exit".equals(line)){//equalsIgnoreCase 忽略大小寫if ("exit".equalsIgnoreCase(line)) {System.out.println("錄入已停止");break;}fos.write(line.getBytes(StandardCharsets.UTF_8));}fos.close();} }文件追加模式案例
package io;import java.io.FileOutputStream; import java.nio.charset.StandardCharsets; import java.util.Scanner;/*** @author少珩* @data 2022/3/7 20:11* 實(shí)現(xiàn)簡(jiǎn)易的記事本工具* 程序啟動(dòng)后,要求將控制臺(tái)輸入的每一行的字符串都寫入到文件note.txt中,* 當(dāng)在控制臺(tái)輸入exit時(shí),程序退出*/ public class TestNotes2 {public static void main(String[] args) throws Exception {System.out.println("請(qǐng)開(kāi)始輸入內(nèi)容,單獨(dú)輸入exit退出");/*文件流有兩種創(chuàng)建模式,覆蓋模式和追加模式構(gòu)造器:FileOutputStream(String path)FileOutputStream(File file)以上兩種的創(chuàng)建方式默認(rèn)都是覆蓋模式,每次執(zhí)行都會(huì)先清除原有文件的內(nèi)容FileOutputStream(String path,boolean append)FileOutputStream(File file,boolean append)如果第二個(gè)參數(shù)傳入true,則文件流為追加模式,此時(shí)連接的文件如果有內(nèi)容,則會(huì)保留原有的內(nèi)容*/FileOutputStream fos =new FileOutputStream("./DAY02/note.txt",true);Scanner scanner = new Scanner(System.in);while (true) {String line = scanner.nextLine();if ("exit".equalsIgnoreCase(line)) {System.out.println("錄入已停止");break;}fos.write(line.getBytes(StandardCharsets.UTF_8));}fos.close();} }處理流
緩沖流
- BufferedOutputStream緩沖輸出流
- BufferedInputStream 緩沖輸入流
復(fù)制文件代碼案例
package io;import java.io.*;/*** @author少珩* @data 2022/3/7 21:09*/ public class CopyDemo3 {public static void main(String[] args) throws Exception {//給源文件插上低級(jí)流,文件輸入字節(jié)流FileInputStream fis = new FileInputStream("./DAY02/demo.jpg");//為fis插上高級(jí)流,緩沖字節(jié)輸入流BufferedInputStream bis = new BufferedInputStream(fis);//給目標(biāo)文件插上低級(jí)流,文件輸出字節(jié)流FileOutputStream fos = new FileOutputStream("./DAY02/demo_cpp.jpg");//為fos插上高級(jí)流,緩沖字節(jié)輸出流BufferedOutputStream bos = new BufferedOutputStream(fos);//測(cè)試單字節(jié)的讀寫int d;long start = System.currentTimeMillis();//由于此處讀的字節(jié)是經(jīng)過(guò)高級(jí)流處理過(guò)的,所以使用高級(jí)流讀while((d=bis.read())!=-1){bos.write(d);}long end = System.currentTimeMillis();System.out.println("耗時(shí):"+(end-start)+"毫秒");//69ms//關(guān)閉流,只需要關(guān)閉高級(jí)流即可會(huì)自動(dòng)關(guān)閉和他相連的低級(jí)流bis.close();bos.close();} }flush代碼案例
package io;import java.io.BufferedOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.charset.StandardCharsets;/*** @author少珩* @data 2022/3/7 21:30* 緩沖流寫出數(shù)據(jù)的緩沖區(qū)問(wèn)題*/ public class BOSFlushDemo {public static void main(String[] args) throws Exception {FileOutputStream fos = new FileOutputStream("./DAY02/bos.txt");//緩沖流內(nèi)部默認(rèn)是一個(gè)8K的字節(jié)數(shù)組,寫出的數(shù)據(jù)會(huì)先存入到數(shù)組中,知道數(shù)組裝滿了才會(huì)寫出BufferedOutputStream bos = new BufferedOutputStream(fos);bos.write("我們的祖國(guó)是花園".getBytes(StandardCharsets.UTF_8));System.out.println("寫出完畢");/*此處能寫出的原因不是因?yàn)閏lose,主要原因是因?yàn)閒lush方法作用:讓緩存輸出流將其緩沖區(qū)的已經(jīng)緩存的數(shù)據(jù)立即寫出*/bos.close();} }對(duì)象流
Person代碼
package io;import java.io.Serializable; import java.util.Arrays;/*** @author少珩* @data 2022/3/7 22:06* 使用當(dāng)前類測(cè)試對(duì)象流的序列化與反序列化操作* 序列化:將內(nèi)存中的對(duì)象按照其結(jié)構(gòu)轉(zhuǎn)換為一組字節(jié),存儲(chǔ)到文件中的過(guò)程* 反序列化:將文件中的內(nèi)容讀取到內(nèi)存中,轉(zhuǎn)換為對(duì)象的過(guò)程* 如果一個(gè)類需要被序列化,這個(gè)類必須要實(shí)現(xiàn)一個(gè)Serializable接口*/ public class Person implements Serializable {/*當(dāng)一個(gè)類實(shí)現(xiàn)了可序列化接口后,最好顯示的定義下面的屬性:serialVersionUID既:序列化版本號(hào)當(dāng)對(duì)象輸出流在進(jìn)行序列化時(shí),會(huì)查看是否有顯示的序列化版本號(hào),如果沒(méi)有,就自動(dòng)根據(jù)當(dāng)前類的結(jié)構(gòu)動(dòng)態(tài)生成一個(gè)唯一在的版本號(hào),只要結(jié)構(gòu)不發(fā)生變化,版本號(hào)就不會(huì)發(fā)生變化重點(diǎn):當(dāng)使用對(duì)象輸入流反序列化時(shí),對(duì)象輸入流會(huì)檢查要反序列化的對(duì)象與其對(duì)應(yīng)的類(比如我們反序列化一個(gè)之前的person對(duì)象)的版本號(hào)是否一致,如果不一致,則會(huì)拋出異常:java.io.InvalidClassException,比如OOSDemo序列化一個(gè)Person對(duì)象,并寫入文件后,我們?cè)赑erson上添加一個(gè)新屬性salary,此處Person類,發(fā)生了變化,那么再使用OISDemo反序列化文件,就會(huì)發(fā)生異常,就是因?yàn)榘姹咎?hào)不一樣了如果后期修改了類結(jié)構(gòu),還不希望不能反序列化原來(lái)的對(duì)象,則需要顯示的定義出來(lái)序列化版本號(hào),這樣一來(lái),當(dāng)一個(gè)對(duì)象序列化后,當(dāng)前類結(jié)構(gòu)即使發(fā)生了變化,只要版本號(hào)不變,依舊是可以反序列化的*/static final long serialVersionUID = 42L;private String name;//姓名private Integer age;//年齡private String gender;//性別/*當(dāng)一個(gè)屬性被transient關(guān)鍵字修飾了,那么當(dāng)這個(gè)對(duì)象被序列化時(shí),這個(gè)屬性的值就會(huì)被忽略,提高程序的響應(yīng)速度,當(dāng)然,反序列化時(shí),這個(gè)屬性的值是默認(rèn)值*/private transient String[] otherInfo;//其他信息private int salary;//薪資//生成全參構(gòu)造,set,get,toString//alt+insert@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +", otherInfo=" + Arrays.toString(otherInfo) +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String[] getOtherInfo() {return otherInfo;}public void setOtherInfo(String[] otherInfo) {this.otherInfo = otherInfo;}public Person(String name, Integer age, String gender, String[] otherInfo) {this.name = name;this.age = age;this.gender = gender;this.otherInfo = otherInfo;} }OOSDemo案例
package io;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.ObjectOutputStream;/*** @author少珩* @data 2022/3/7 22:14* OOS ObjectOutputStream* OIS ObjectInputStream* 對(duì)象流是一對(duì)高級(jí)流,在流連接中完成對(duì)象與字節(jié)的轉(zhuǎn)換,即序列化與反序列化*/ public class OOSDemo {public static void main(String[] args) throws Exception {String name="馮翔";int age = 24;String gender = "男";String[] otherInfo = {"是一個(gè)男的","來(lái)自北京","愛(ài)好女","是個(gè)帥氣的海王"};Person p = new Person(name, age, gender, otherInfo);//Person中重寫了toString方法System.out.println(p);//將Person對(duì)象寫入到person.obj文件中FileOutputStream fos = new FileOutputStream("./DAY02/person.obj");ObjectOutputStream oos = new ObjectOutputStream(fos);/*writeObject(p); 對(duì)象輸出流中提供獨(dú)特的方法該方法可以將對(duì)象序列化,并將序列化后的字節(jié)通過(guò)其連接的流寫出*/oos.writeObject(p);System.out.println("寫出完畢");oos.close();} }OISDemo案例
package io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.ObjectInputStream;/*** @author少珩* @data 2022/3/9 19:56* 使用對(duì)象輸入流進(jìn)行對(duì)象的反序列化*/ public class OISDemo {public static void main(String[] args) throws Exception {FileInputStream fis = new FileInputStream("./DAY02/person.obj");ObjectInputStream ois = new ObjectInputStream(fis);//readObject 讀取文件中的對(duì)象,返回的是Object類型Person p = (Person) ois.readObject();p.setAge(18);System.out.println(p);ois.close();} }字節(jié)流和字符流
在Java中,根據(jù)處理的數(shù)據(jù)單位不同,分為字節(jié)流和字符流。
字節(jié)流: 一個(gè)字節(jié)(byte)一個(gè)字節(jié)的去讀取, 或者寫出
字符流: 一個(gè)字符一個(gè)字符的去讀取, 或者寫出
字節(jié)流
字節(jié)流(stream):針對(duì)二進(jìn)制文件(文本,圖片,音頻,視頻…等)
InputStream(包含input都是輸入流)
– FileInputStream
– BufferedInputStream
– ObjectInputStream
OutputStream(包含output都是輸出流)
– FileOutputStream
– BufferedOutputStream
– ObjectOutputStream
字符流
字符流(Reader,Writer):針對(duì)文本文件,讀寫容易發(fā)生亂碼現(xiàn)象,在讀寫時(shí)最好指定編碼集為utf-8
Reader(Reader結(jié)尾的都是字符輸入流)
– FileReader
– BufferedReader
– InputStreamReader
Writer(Writer結(jié)尾的都是字符輸出流)
– FileWriter
– BufferedWriter
– OutputStreamWriter
– PrintWriter/PrintStream
轉(zhuǎn)換字符流
OutputStreamWriter
代碼案例
package io;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets;/*** @author少珩* @data 2022/3/9 20:56* OSW OutputStreamWriter* java.io將流按照讀寫單位劃分為字節(jié)流和字符流* InputStream和OutputStream是所有字節(jié)輸入與輸出流的超類,讀寫的最小單位是字節(jié)* Reader和Writer是所有字符輸入和輸出流的超類,讀寫的最小單位是字符* 字符流只適合讀寫文本,像圖片,音頻等字節(jié)文件不適合* 字符流的底層本質(zhì)還是字節(jié)流,只是字符與字節(jié)的轉(zhuǎn)換由字符流自行完成* InputStreamReader和OutputStreamWriter是一對(duì)高級(jí)流*/ public class OSWDemo {public static void main(String[] args) throws Exception {//向osw.txt中寫入字符串FileOutputStream fos = new FileOutputStream("./DAY02/osw.txt");//在創(chuàng)建轉(zhuǎn)換流時(shí),通常需要指定第二個(gè)參數(shù),明確使用的編碼OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);osw.write("我可以接收你的所有的小脾氣");osw.write("我可以帶你吃很多的好東西");System.out.println("寫出完畢");osw.close();} }InputStreamReader
代碼案例
package io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets;/*** @author少珩* @data 2022/3/9 21:07* ISR InputStreamReader*/ public class ISRDemo {public static void main(String[] args) throws Exception {//將osw.txt的內(nèi)容讀取出來(lái)FileInputStream fis = new FileInputStream("./DAY02/osw.txt");InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);int d;while((d=isr.read())!=-1){System.out.print((char)d);}isr.close();} }緩沖字符流
PrintWriter
代碼案例
package io;import java.io.FileNotFoundException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets;/*** @author少珩* @data 2022/3/9 21:19* PW PrintWriter* 緩沖字符流* BufferWriter和BufferReader** PrintWriter 具有自動(dòng)行刷新功能的緩沖字符輸出流,內(nèi)部會(huì)自動(dòng)連接BufferWriter* 特點(diǎn):* 按行讀寫字符串* 自動(dòng)行刷新* 可以提高寫出字符串的效率*/ public class PwDemo {public static void main(String[] args) throws Exception {/*構(gòu)造方法,還有第二個(gè)參數(shù)允許傳入一個(gè)字符串指定編碼需要注意,此處不能傳遞StandardCharsets.UTF_8,當(dāng)時(shí)還沒(méi)有StandardCharsets類呢所以此處傳參時(shí),由于是字符串,所以容易寫錯(cuò),大小寫均可*/PrintWriter pw = new PrintWriter("./DAY02/pw.txt","UTF-8");pw.println("大河向東流");pw.println("天上的星星參北斗啊~~~");System.out.println("寫出完畢");pw.close();} }代碼案例2
package io;import java.io.*; import java.util.Scanner;/*** @author少珩* @data 2022/3/9 21:55* 在流連接中使用PW*/ public class PWDemo2 {public static void main(String[] args) throws Exception {//向pw2.txt文件寫入內(nèi)容//1.創(chuàng)建文件字節(jié)輸出流,是一個(gè)低級(jí)流//加上true可以將當(dāng)前的流改為追加模式FileOutputStream fos = new FileOutputStream("./DAY02/pw2.txt",true);//2.創(chuàng)建一個(gè)轉(zhuǎn)換字符輸出流,是一個(gè)高級(jí)流,//銜接字符與字節(jié)的流,將寫出的字符串轉(zhuǎn)換為字節(jié)OutputStreamWriter oos = new OutputStreamWriter(fos);//3.緩沖輸出流,是一個(gè)高級(jí)流,塊寫入到文件中BufferedWriter bw = new BufferedWriter(oos);//4.緩沖字符輸出流/*PrintWriter 構(gòu)造方法有第二個(gè)參數(shù),是布爾值當(dāng)該值是true時(shí),會(huì)自動(dòng)打開(kāi)行刷新功能,這意味著我們每次調(diào)用println方法后會(huì)自動(dòng)調(diào)用flush*/PrintWriter pw = new PrintWriter(bw,true);Scanner scanner = new Scanner(System.in);System.out.println("請(qǐng)輸入想要錄入到文檔中的內(nèi)容");//接收控制臺(tái)輸入字符串//完成簡(jiǎn)易的記事本,控制臺(tái)輸入每行字符串,按行寫入文件,單獨(dú)輸入exit,退出while(true){//crtl+shift+↑↓ 可以上下移動(dòng)當(dāng)前行代碼String s = scanner.nextLine();//equalsIgnoreCase 忽略大小寫比較if("exit".equalsIgnoreCase(s)){break;}pw.println(s);}pw.close();} }總結(jié)
- 上一篇: 【整理向】老板让我用SPSS做A/Bte
- 下一篇: 软件安全与脆弱性分析-对于freenot