IO流缓冲流等高级流
生活随笔
收集整理的這篇文章主要介紹了
IO流缓冲流等高级流
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
IO流緩沖流等高級流
回顧
1 File類 表示硬盤中一個文件或文件夾(目錄)文件: //1.1創(chuàng)建對象File file=new File("d:\\123.txt");//1.2判斷文件是否存在if(!file.exists()){file.createNewFile();}//1.3刪除file.delete();file.deleteOnExit();//退出jvm,刪除文件//1.4可執(zhí)行、可讀、可寫file.canExecute();file.canRead();file.canWrite();//1.5獲取file.getAbsoulatePath();file.getPath();file.getName();file.getParent();file.lastModified();//修改時間//1.6判斷file.isFile();file.isHidden();file.renameTo();//重命名文件夾 ://2.1創(chuàng)建文件夾File dir=new File("d:\\aaa\\bbb");//2.2判斷是否存在if(!dir.exists()){dir.mkdir();//一級目錄dir.mkdirs();//多級目錄}//2.3刪除dir.delete();dir.deleteOnExit();//2.4獲取dir.getAbsoulatePath();dir.getPath();dir.getName();dir.getParent();//2.5判斷dir.isDirectory();dir.isHidden();dir.renameTo();//2.6列出來當(dāng)前目錄下的文件和文件夾dir.list();//String[]dir.listFiles();//File[]dir.list(FileNameFilter);File.listRoots();//返回所有的盤符2遞歸遍歷文件夾中所有的文件和子文件3遞歸刪除文件夾4 IO (Input Output)流:是數(shù)據(jù)傳輸?shù)耐ǖ?。輸? 從外部存儲到內(nèi)存(java程序)(讀取)輸出: 從內(nèi)存到外部存儲 (寫入)IO分類 :1 按照流向 輸入流和輸出流2 按照字節(jié)個數(shù) 字節(jié)流和字符流3 按照功能 節(jié)點(diǎn)流和處理流5 字節(jié)流 InputStream ----> FileInputStreamOutputStream ---->FileOutputStream6 字符流Reader ----->InputStreamReader---->FileReaderWriter ----->OutputStreamWriter ---->FileWriter7 轉(zhuǎn)換流 InputStreamReader:字節(jié)流通向字符流的橋梁,指定編碼OutputStreamWriter:字符流通向字節(jié)流的橋梁,指定編碼8 復(fù)制文件使用字節(jié)流復(fù)制今天內(nèi)容
1.緩沖流2.1 BufferedInputStream類的使用2.2 BufferedOutputStream類的使用2.3 BufferedReader類的使用2.4 BufferedWriter類的使用 2.內(nèi)存流 3.標(biāo)準(zhǔn)輸入輸出流 4.對象流 5.RandomAccessFile類 6.Properties類 7.裝飾者設(shè)計(jì)模式教學(xué)目標(biāo)
1.掌握緩沖、內(nèi)存流的使用 2.了解標(biāo)準(zhǔn)輸入輸出流的使用 3.掌握對象流的使用 4.了解RandomAccessFile類的使用 5.掌握Properties的使用 6.了解裝飾者設(shè)計(jì)模式第一節(jié) 緩沖流
作用:主要是為了增強(qiáng)基礎(chǔ)流的功能而存在的,提高了流的工作效率【讀寫效率】注意:如果使用記事本創(chuàng)建的文件,文件是utf-8或者unicode編碼,文件的前面有一個BOM(Byte Order Mark)頭,BOM作用指定文件使用的編碼類型。GBK編碼沒有添加bom頭。 utf-8:EF BB BF unicode 小端: FF FE 66 00 unicode 大端 :FE FF 00 661.1 BufferedInputStream類
public class BufferedInputStreamDemo {public static void main(String[] args) throws IOException {//實(shí)例化一個File對象File file = new File("file/test22.txt");//實(shí)例化一個緩沖字節(jié)輸入流的對象BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));/*//讀取byte[] arr = new byte[1024];int len = 0;while((len = input.read(arr)) != -1) {String string = new String(arr, 0, len);}*/byte[] arr = new byte[4];int len = input.read(arr);String string = new String(arr, 0, len);System.out.println(string);input.mark(66);len = input.read(arr);string = new String(arr, 0, len);System.out.println(string);// 實(shí)現(xiàn)了效果:覆水可收input.reset();len = input.read(arr);string = new String(arr, 0, len);System.out.println(string);input.close();} }1.2 BufferedOutputStream類
public class BufferedOutputStreamDemo {public static void main(String[] args) throws IOException {//實(shí)例化FIle對象File file = new File("test33.txt");//實(shí)例化換種字節(jié)輸出流 BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));//寫output.write("你好的halle".getBytes());//刷新output.flush();//關(guān)閉output.close();} }1.3 BufferedReader類
public class BufferedReaderDemo {public static void main(String[] args) throws IOException {//實(shí)例化FIle對象File file = new File("test33.txt");//實(shí)例化緩沖字符流的對象BufferedReader reader = new BufferedReader(new FileReader(file));//方式一:read循環(huán)讀取/*//讀取char[] arr = new char[8];int len = 0;while((len = reader.read(arr)) != -1) {String string = new String(arr, 0, len);}*///方式二:readLine循環(huán)讀取/*String result1 = reader.readLine();System.out.println(result1);String result2 = reader.readLine();System.out.println(result2);*/String result = "";while((result = reader.readLine()) != null) {System.out.println("第一行:" + result);}reader.close();} }1.4 BufferedWriter類
public class BufferedWriterDemo {public static void main(String[] args) throws IOException {// 實(shí)例化FIle對象File file = new File("test33.txt");//實(shí)例化緩沖字符輸出流BufferedWriter writer = new BufferedWriter(new FileWriter(file,true));// 寫writer.write("今天天氣還可以");// 作用:主要就是為了換行writer.newLine();// 刷新writer.flush();//關(guān)閉writer.close();} }第二節(jié) 內(nèi)存流
輸入和輸出都是從文件中來的,當(dāng)然,也可將輸出輸入的位置設(shè)置在內(nèi)存上,這就需要ByteArrayInputStream和ByteArrayOutputStreamByteArrayInputStream:將內(nèi)容寫入到內(nèi)存中,是Inputstream的子類ByteArrayOutputStream:將內(nèi)存中數(shù)據(jù)輸出,是OutputStream的子類此時的操作應(yīng)該以內(nèi)存為操作點(diǎn)案例:完成一個字母大小寫轉(zhuǎn)換的程序
public class TextDemo02 {public static void main(String[] args) throws IOException {//定義一個字符串,全部由大寫字母組成String string = "HELLOWORLD";//內(nèi)存輸入流//向內(nèi)存中輸出內(nèi)容,注意:跟文件讀取不一樣,不設(shè)置文件路徑ByteArrayInputStream bis = new ByteArrayInputStream(string.getBytes());//內(nèi)存輸出流//準(zhǔn)備從內(nèi)存中讀取內(nèi)容,注意:跟文件讀取不一樣,不設(shè)置文件路徑ByteArrayOutputStream bos = new ByteArrayOutputStream();int temp = 0;//read()方法每次只讀取一個字符while((temp = bis.read()) != -1) {//將讀取的數(shù)字轉(zhuǎn)為字符char c = (char)temp;//將字符變?yōu)榇髮?/span>bos.write(Character.toLowerCase(c));}//循環(huán)結(jié)束之后,所有的數(shù)據(jù)都在ByteArrayOutputStream中//取出內(nèi)容,將緩沖區(qū)內(nèi)容轉(zhuǎn)換為字符串String newString = bos.toString();//關(guān)閉流bis.close();bos.close();System.out.println(newString);} } 實(shí)際上以上操作很好體現(xiàn)了對象的多態(tài)。通過實(shí)例化其子類不同,完成的功能也不同,也就相當(dāng)于輸出的位置不同,如果是輸出文件,則使用FileXxxx類。如果是內(nèi)存,則使用ByteArrayXxx??偨Y(jié): a.內(nèi)存操作流的操作對象,一定是以內(nèi)存為主準(zhǔn),不要以硬盤為準(zhǔn)。b.實(shí)際上此時可以通過向上轉(zhuǎn)型的關(guān)系,為OutputStream或InputStream.c.內(nèi)存輸出流在日后的開發(fā)中也是經(jīng)常使用到,所以一定要重點(diǎn)掌握第三節(jié) 標(biāo)準(zhǔn)輸入輸出流
Java的標(biāo)準(zhǔn)輸入/輸出分別通過System.in和System.out實(shí)現(xiàn),默認(rèn)情況下分別代表是鍵盤和顯示器 public class PrintStreamDemo {public static void main(String[] args) throws FileNotFoundException {//System.out.println("hello world");//創(chuàng)建打印流的對象//注意:默認(rèn)打印到控制臺,但是,如果采用setOut方法進(jìn)行重定向之后,將輸出到指定的文件中PrintStream print = new PrintStream(new FileOutputStream(new File("test33.txt")));/** static void setErr(PrintStream err) 重新分配“標(biāo)準(zhǔn)”錯誤輸出流。 static void setIn(InputStream in) 重新分配“標(biāo)準(zhǔn)”輸入流。 static void setOut(PrintStream out) 重新分配“標(biāo)準(zhǔn)”輸出流。 * *///將標(biāo)準(zhǔn)輸出重定向到print的輸出流System.setOut(print);System.out.println("hello world");} } public class InputStreamDemo {public static void main(String[] args) throws FileNotFoundException {FileInputStream inputStream = new FileInputStream(new File("test33.txt"));//setInSystem.setIn(inputStream);//System.out.println("請輸入內(nèi)容:");//默認(rèn)情況下是從控制臺進(jìn)行獲取內(nèi)容//但是如果使用setIn方法設(shè)置了重定向之后,將從指定文件中獲取內(nèi)容Scanner sc = new Scanner(System.in);String string = sc.next();System.out.println(string);} }第四節(jié) 對象流
流中流動的數(shù)據(jù)是對象將一個對象寫入到本地文件中,被稱為對象的序列化將一個本地文本中的對象讀取出來,被稱為對象的反序列化 使用對象流ObjectInputStream: 對象輸出流ObjectOutputStream:對象輸入流注意:一個對象流只能操作一個對象,如果試圖采用一個對象流操作多個對象的話,會出現(xiàn)EOFException【文件意外達(dá)到了文件末尾】如果向?qū)⒍鄠€對象序列化到本地,可以借助于集合,【思路:將多個對象添加到集合中,將集合的對象寫入到本地文件中,再次讀出來,獲取到的仍然是集合對象,遍歷集合】對象中那些字段可以不序列化:1 transient 修飾的字段2 靜態(tài)的字段 在要序列化類中添加字段,保證序列化和反序列化是同一個類 private static final long serialVersionUID = 100L; public class ObjectStreamDemo {public static void main(String[] args) {// TODO Auto-generated method stub//objectOutputStreamUsage();objectInputStreamUsage();}// 寫:將對象進(jìn)行序列化public static void objectOutputStreamUsage() {//1.實(shí)例化一個Person的對象Person person = new Person("張三", 10, 'B');//2.實(shí)例化一個對象輸出流的對象ObjectOutputStream output = null;try {output = new ObjectOutputStream(new FileOutputStream(new File("file/person.txt")));//3.將對象寫入到流中output.writeObject(person);//4.刷新output.flush();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {try {output.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}// 讀:反序列化public static void objectInputStreamUsage() {//1.實(shí)例化對象輸入流的對象try {ObjectInputStream input = new ObjectInputStream(new FileInputStream(new File("file/person.txt")));//2.讀取Object object = input.readObject();//3.對象的向下轉(zhuǎn)型if(object instanceof Person) {Person p = (Person)object;System.out.println(p);}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}} } 注意:在使用對象流的時候,用于初始化對象流的參數(shù)只能是字節(jié)流(將對象轉(zhuǎn)換為二進(jìn)制的形式,然后再把二進(jìn)制寫入文件)第五節(jié) RandomAccessFile類
RandomAccessFile是用來訪問那些保存數(shù)據(jù)記錄的文件的,你就可以用seek( )方法來訪問記錄,并進(jìn)行讀寫了。這些記錄的大小不必相同;但是其大小和位置必須是可知的。但是該類僅限于操作文件。案例一:RandomAccessFile類的應(yīng)用
public class TextDemo01 {public static void main(String[] args) throws Exception {RandomAccessFile file = new RandomAccessFile("file.txt", "rw");// 以下向file文件中寫數(shù)據(jù)file.writeInt(20);// 占4個字節(jié)file.writeDouble(8.236598);// 占8個字節(jié)//這個長度寫在當(dāng)前文件指針的前兩個字節(jié)處,可用readShort()讀取file.writeUTF("這是一個UTF字符串");file.writeBoolean(true);// 占1個字節(jié)file.writeShort(395);// 占2個字節(jié)file.writeLong(2325451l);// 占8個字節(jié)file.writeUTF("又是一個UTF字符串");file.writeFloat(35.5f);// 占4個字節(jié)file.writeChar('a');// 占2個字節(jié)//把文件指針位置設(shè)置到文件起始處file.seek(0);// 以下從file文件中讀數(shù)據(jù),要注意文件指針的位置System.out.println("——————從file文件指定位置讀數(shù)據(jù)——————");System.out.println(file.readInt());System.out.println(file.readDouble());System.out.println(file.readUTF());//將文件指針跳過3個字節(jié),本例中即跳過了一個boolean值和short值。file.skipBytes(3);System.out.println(file.readLong());//跳過文件中“又是一個UTF字符串”所占字節(jié)//注意readShort()方法會移動文件指針,所以不用寫2。file.skipBytes(file.readShort()); System.out.println(file.readFloat());// 以下演示文件復(fù)制操作System.out.println("——————文件復(fù)制(從file到fileCopy)——————");file.seek(0);RandomAccessFile fileCopy = new RandomAccessFile("fileCopy.txt", "rw");int len = (int) file.length();// 取得文件長度(字節(jié)數(shù))byte[] b = new byte[len];//全部讀取file.readFully(b);fileCopy.write(b);System.out.println("復(fù)制完成!");} }第六節(jié) Properties類
是Map接口的一個實(shí)現(xiàn)類,并且是Hashtable的子類Properties文件中元素也是以鍵值對的形式存在的 Properties特點(diǎn): 1 存儲屬性名和屬性值 2 屬性名和屬性值都是字符串 3 和流有關(guān)系 4 沒有泛型 public class PropertiesDemo {public static void main(String[] args) {//1.實(shí)例化一個Properties的對象Properties pro = new Properties();System.out.println(pro);//2.把文件userlist.properties中的鍵值對同步到集合中//實(shí)質(zhì):讀取/*** void load(InputStream inStream) 從輸入流中讀取屬性列表(鍵和元素對)。 */try {pro.load(new BufferedInputStream(new FileInputStream(new File("file/userlist.properties"))));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(pro);//3.向集合中添加一對鍵值對/** Object setProperty(String key, String value) 調(diào)用 Hashtable 的方法 put。 * */pro.setProperty("address", "china");System.out.println(pro);try {//4.store//實(shí)質(zhì):寫入//comments:工作日志pro.store(new BufferedOutputStream(new FileOutputStream(new File("file/userlist.properties"))), "add a pair of key and value");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}} }第七節(jié) 裝飾者設(shè)計(jì)模式
裝飾者模式是向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。它是通過創(chuàng)建一個包裝對象,也就是裝飾來包裹真實(shí)的對象。應(yīng)用場景:需要擴(kuò)展、增強(qiáng)一個類的功能,或給一個類添加附加職責(zé)。 擴(kuò)展類的功能有兩種實(shí)現(xiàn)方法:1 繼承重寫優(yōu)點(diǎn):簡單缺點(diǎn):1 類體系太龐大 2 耦合性太高 3子類繼承不需要的方法2 裝飾者模式缺點(diǎn):多層裝飾比較復(fù)雜優(yōu)點(diǎn):耦合性低,提高重用性,符合合成(聚合)復(fù)用原則java面向?qū)ο蟮脑O(shè)計(jì)原則 7大原則開(總則) 開閉原則, 對擴(kuò)展開放,對修改關(guān)閉口 :接口隔離原則,使用接口隔離,降低程序耦合性合 :合成聚合復(fù)用,不用繼承,使用組合(強(qiáng)擁有關(guān)聯(lián))、聚合(弱擁有關(guān)聯(lián)) 學(xué)校類 (List<Student>)里 : 里氏替換原則,多態(tài) 父類能使用的地方,都可以替換成子類 Animal animal=new Dog();最 :最少知道原則(迪米特法則),一個類不要知道太多其他的類單: 單一職責(zé)原則,一個類只負(fù)責(zé)一類功能,如果一個類功能太多,需要拆分。依: 依賴倒置原則,不依賴具體的類,依賴接口或抽象類。降低程序耦合性代碼實(shí)現(xiàn):
/*** 抽象人類* @author wgy**/ public abstract class AbstractPerson {public abstract void eat(); } /** *子類1 */ public class Student extends AbstractPerson {String name;String school;public void eat() {System.out.println(name+"正在吃東西.........");}} package com.qf.day18_6; /*** 子類2* @author wgy**/ public class Teacher extends AbstractPerson{String name;int workyear;@Overridepublic void eat() {System.out.println(name+"吃......");}} package com.qf.day18_6;import java.io.BufferedInputStream;/*** 增強(qiáng)Person* @author wgy**/ public class StrongPerson extends AbstractPerson {//使用person創(chuàng)建一個變量AbstractPerson p;public StrongPerson(AbstractPerson p) {this.p = p;}public void eat() {p.eat();System.out.println("抽一口");System.out.println("瞇一會");System.out.println("寫會java代碼");}} //測試類 package com.qf.day18_6;public class Test {public static void main(String[] args) {Student benwei=new Student();benwei.name="本偉";Teacher zhengshuai=new Teacher();zhengshuai.name="鄭帥";StrongPerson strongPerson=new StrongPerson(benwei);StrongPerson strongPerson2=new StrongPerson(zhengshuai);strongPerson.eat();strongPerson2.eat();} }擴(kuò)展案例:
1 抽象類 ReadFile -->read抽象方法 2 定義一些子類ReadTextFile 讀取文本文件ReadMusicFile 讀取音樂文件ReadVideoFile 讀取視頻文件 3 要求:提高三個類的功能 帶緩沖 3.1繼承BufferedReadTextFile繼承ReadTextFile 重寫 read方法BufferedReadMusicFile繼承ReadMusicFile 重寫 readBufferedReadVideoFile繼承ReadVideoFile 重寫 read缺點(diǎn):1 類體系太龐大 2 耦合性太高3.2裝飾者設(shè)計(jì)模式 :采用組合的關(guān)系BufferedReadFile{private ReadFile readFile;public BufferedReadFile(ReadFile readFile){this.readFile=readFile;}public void read(){///}}總結(jié)
1 緩沖流BufferedInputStreamBufferedOutputStreamBufferedReader readLine();BufferedWriter newLine(); 2 內(nèi)存流ByteArrayInputStreamByteArrayOutputStream 3 標(biāo)準(zhǔn)輸入輸出流System.inSystem.out PrintStream打印流 4 對象流ObjectInputStreamObjectOutputStream序列化反序列化 5 RandomAccessFile類 6 Properties集合 7 裝飾者設(shè)計(jì)模式默寫
1.使用轉(zhuǎn)換流實(shí)現(xiàn)文件內(nèi)容的拷貝2.使用字符緩沖流實(shí)現(xiàn)文件內(nèi)容的拷貝作業(yè)
1.在電腦中盤下創(chuàng)建一個文件為HelloWorld.txt文件,判斷他是文件還是目錄,在創(chuàng)建一個目錄FileTest,之后將HelloWorld.txt移動到FileText目錄下去 2.在程序中寫一個"HelloJavaWorld你好世界"輸出到操作系統(tǒng)文件Hello.txt文件中 3.從磁盤讀取一個文件到內(nèi)存中,再打印到控制臺 4.統(tǒng)計(jì)一個含有英文單詞的文本文件的單詞個數(shù) 5.從磁盤讀取一個文件到內(nèi)存中,再打印到控制臺 6.實(shí)現(xiàn)將一個文件夾中的一張圖片拷貝到另外一個文件夾下 7.將上課關(guān)于不同的流實(shí)現(xiàn)拷貝的案例敲熟練 8.定義一個類Student,定義屬性:學(xué)號、姓名和成績,方法:show(顯示個人信息)實(shí)例化幾個Student對象,將這幾個對象保存到student.txt文件中然后再將文件中的內(nèi)容讀取出來并且調(diào)用show方法9.從控制臺輸入一個字符串,統(tǒng)計(jì)其中一個字符出現(xiàn)的次數(shù) 10.理解裝飾者設(shè)計(jì)模式,并實(shí)現(xiàn)類似課堂案例的案例作業(yè)答案關(guān)注 +私信哦
面試題
1.BufferedReader屬于哪種流,它主要是用來做什么的,它里面有那些經(jīng)典的方法 2.怎么樣把輸出字節(jié)流轉(zhuǎn)換成輸出字符流,說出它的步驟 3.流一般需要不需要關(guān)閉,如果關(guān)閉的話在用什么方法,一般要在那個代碼塊里面關(guān)閉比較好,處理流是怎么關(guān)閉的,如果有多個流互相調(diào)用傳入是怎么關(guān)閉的? 4.什么叫對象序列化,什么是反序列化,實(shí)現(xiàn)對象序列化需要做哪些工作 5.在實(shí)現(xiàn)序列化接口是時候一般要生成一個serialVersionUID字段,它叫做什么,一般有什么用 6.什么是內(nèi)存流?有什么作用總結(jié)
以上是生活随笔為你收集整理的IO流缓冲流等高级流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。