深入理解JAVA IO流
2022-08-05 09:04·Java開發(fā)技術(shù)分享目錄
1.字符輸入流BufferedReader
2.字符輸出流BufferedWriter
聾緩沖流
(1)帶有緩沖區(qū)的字符輸入流;使用這個(gè)流的時(shí)候 不需要自定義char數(shù)組 ,或者說不需要自定義byte數(shù)組;自帶緩沖!
(2)讀取數(shù)據(jù)時(shí), 可以一次性讀取一行
(3)這里只講解字符緩沖流: java.io.BufferedReader 和 java.io.BufferedWriter ;字節(jié)緩沖流使用方法是一樣的
(4)BufferedReader和BufferedWriter都是包裝流!
1.字符輸入流BufferedReader
package com.bjpowernode.java.io;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;public class BufferedReaderTest01 { public static void main(String[] args) throws Exception { FileReader reader = new FileReader("file"); // 當(dāng)一個(gè)流的構(gòu)造方法中需要一個(gè)流的時(shí)候,這個(gè)被傳進(jìn)來的流叫做:節(jié)點(diǎn)流。 // 外部負(fù)責(zé)包裝的這個(gè)流,叫做:包裝流或者叫做:處理流。 // FileReader就是一個(gè)節(jié)點(diǎn)流。BufferedReader就是包裝流/處理流。 BufferedReader br = new BufferedReader(reader); // 只能傳字符流 // 優(yōu)點(diǎn):一次能讀一行;但不帶換行符! String s = null; while((s = br.readLine()) != null){ // br.readLine()返回的是一個(gè)字符串 System.out.println(s); } // 關(guān)閉流,只需要關(guān)閉最外層流就行,里面的節(jié)點(diǎn)流會(huì)自動(dòng)關(guān)閉。 br.close(); }}
2.字符輸出流BufferedWriter
package com.bjpowernode.java.io;import java.io.*;public class BufferedWriterTest01 { public static void main(String[] args) throws IOException { // 創(chuàng)建帶有緩沖區(qū)的字符輸出流 BufferedWriter writer = new BufferedWriter(new FileWriter("file")); // 開始寫 writer.write("hello world!"); writer.write("n"); writer.write("hello kitty!"); // 刷新 writer.flush(); // 關(guān)閉最外層 writer.close(); }}
聾轉(zhuǎn)換流
1.OutputStreamWriter
BufferedWriter:帶有緩沖的字符輸出流。OutputStreamWriter:轉(zhuǎn)換流
package com.bjpowernode.java.io;import java.io.*;public class BufferedWriterTest01 { public static void main(String[] args) throws IOException { // 創(chuàng)建帶有緩沖區(qū)的字符輸出流 BufferedWriter writer = new BufferedWriter(new FileWriter("file")); // 如果想要使用字節(jié)輸出流,還是需要OutputStreamWriter進(jìn)行流的轉(zhuǎn)換 // 如果使用的是字節(jié)流 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file")); BufferedWriter writer1 = new BufferedWriter(osw); // 合并在一起 BufferedWriter writer1 = new BufferedWriter(new OutputStreamWriter (new FileOutputStream("file"))); // 開始寫 writer.write("hello world!"); writer.write("n"); writer.write("hello kitty!"); // 刷新 writer.flush(); // 關(guān)閉最外層 writer.close(); }}
2.InputStreamReader
BufferedReader(reader),里面只能傳字符流;那如果是字節(jié)流怎么辦呢?
package com.bjpowernode.java.io;import java.io.*;public class BufferedReaderTest02 { public static void main(String[] args) { FileInputStream fis = null; try { // 字節(jié)流 fis = new FileInputStream("file"); // 通過轉(zhuǎn)換流轉(zhuǎn)換(InputStreamReader將字節(jié)流轉(zhuǎn)換成字符流) // fis是節(jié)點(diǎn)流。reader是包裝流。 InputStreamReader reader = new InputStreamReader(fis); // 把轉(zhuǎn)換成字符流的字節(jié)流,傳過來 // reader是節(jié)點(diǎn)流。br是包裝流。 BufferedReader br = new BufferedReader(reader); // 上面進(jìn)行合并 BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("file"))); // 進(jìn)行打印 String s = null; while((s = br1.readLine()) != null){ System.out.println(s); } // 關(guān)閉 br.close(); // 關(guān)閉最外層 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
聾數(shù)據(jù)流
1.DataOutputStream
(1)java.io.DataOutputStream:數(shù)據(jù)專屬的流;也是一個(gè)包裝流!
(2)這個(gè)流可以 將數(shù)據(jù)連同數(shù)據(jù)的類型一并寫入文件 。
(3)注意:這個(gè)文件不是普通文本文檔。(這個(gè)文件使用記事本打不開)
package com.bjpowernode.java.io;import java.io.DataOutputStream;import java.io.FileOutputStream;public class DataOutputStreamTest01 { public static void main(String[] args) throws Exception{ // 創(chuàng)建數(shù)據(jù)專屬的字節(jié)輸出流(寫) DataOutputStream dos = new DataOutputStream(new FileOutputStream("file")); //生成的這個(gè)文件,記事本打不開 // 寫數(shù)據(jù) byte b = 100; short s = 200; int i = 300; long l = 400L; float f = 3.0F; double d = 3.14; boolean sex = false; char c = 'a'; // 寫;把數(shù)據(jù)以及數(shù)據(jù)的類型一并寫入到文件當(dāng)中 dos.writeByte(b); dos.writeShort(s); dos.writeInt(i); dos.writeLong(l); dos.writeFloat(f); dos.writeDouble(d); dos.writeBoolean(sex); dos.writeChar(c); // 刷新 dos.flush(); // 關(guān)閉最外層 dos.close(); }}
2.DataInputStream
(1)DataInputStream:數(shù)據(jù)字節(jié)輸入流。
(2)DataOutputStream寫的文件,只能使用DataInputStream去讀。并且讀的時(shí)候你需要提前知道寫入的順序;讀的順序需要和寫得順序一致。才可以正常取出數(shù)據(jù) 。
package com.bjpowernode.java.io;import java.io.DataInputStream;import java.io.FileInputStream;public class DataInputStreamTest01 { public static void main(String[] args) throws Exception { // 創(chuàng)建數(shù)據(jù)專屬的字節(jié)輸入流(讀) DataInputStream dis = new DataInputStream(new FileInputStream("file")); // 開始讀 byte b = dis.readByte(); short s = dis.readShort(); int i = dis.readInt(); long l = dis.readLong(); float f = dis.readFloat(); double d = dis.readDouble(); boolean sex = dis.readBoolean(); char c = dis.readChar(); // 打印 System.out.println(b); System.out.println(s); System.out.println(i); System.out.println(l); System.out.println(f); System.out.println(d); System.out.println(sex); System.out.println(c); // 關(guān)閉流 dis.close(); }}
聾標(biāo)準(zhǔn)輸出流
1.PrintStream
(1)jva.io.PrintStream:標(biāo)準(zhǔn)的字節(jié)輸出流。默認(rèn)輸出到控制臺(tái)。
(2)標(biāo)準(zhǔn)輸出流 不需要手動(dòng)close()關(guān)閉 。
(3)可以 通過System.setOut()方法改變輸出流的方向
package com.bjpowernode.java.io;import java.io.FileOutputStream;import java.io.PrintStream;public class PrintStreamTest { public static void main(String[] args) throws Exception { System.out.println("hello world"); // 實(shí)際上上述代碼可以拆分成 PrintStream ps = System.out; ps.println("hello world"); // 可以改變標(biāo)準(zhǔn)輸出流的輸出方向; // 例如:標(biāo)準(zhǔn)輸出流不在指向控制臺(tái),指向log文件 PrintStream printStream = new PrintStream(new FileOutputStream("log")); // 修改輸出方向 System.setOut(printStream); // 輸出 System.out.println("Hello World"); //不會(huì)再輸出到控制臺(tái),而是到log文件 }}
2.日志工具類
那么標(biāo)準(zhǔn)輸出流PrintStream有什么用呢?我們不妨寫一個(gè)簡(jiǎn)單的日志工具類!
日志框架
package com.bjpowernode.java.io;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.text.SimpleDateFormat;import java.util.Date;// 日志工具public class Logger { // 記錄日志的方法 public static void log(String msg) { try { PrintStream out = new PrintStream(new FileOutputStream("log.txt",true)); // 改變流的方向 System.setOut(out); // 獲取系統(tǒng)當(dāng)前時(shí)間 Date nowDate = new Date(); // 格式類型轉(zhuǎn)換 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String myNowdate = sdf.format(nowDate); // 打印 System.out.println(myNowdate+":"+msg); } catch (FileNotFoundException e) { e.printStackTrace(); } }}
日志測(cè)試
package com.bjpowernode.java.io;public class LoggerTest { public static void main(String[] args) { // 測(cè)試日志工具類 Logger.log("調(diào)用了System類的gc()方法,建議啟動(dòng)垃圾回收"); Logger.log("調(diào)用了UserService的doSome()方法"); Logger.log("用戶嘗試進(jìn)行登錄,驗(yàn)證失敗"); // 在log.txt打印的結(jié)果 /* 2022-07-22 08:47:49 667:調(diào)用了System類的gc()方法,建議啟動(dòng)垃圾回收 2022-07-22 08:47:49 703:調(diào)用了UserService的doSome()方法 2022-07-22 08:47:49 714:用戶嘗試進(jìn)行登錄,驗(yàn)證失敗*/ }}
聾File類的理解
java.io.File
1、File類和四大家族沒有關(guān)系,所以File類不能完成文件的讀和寫。
2、File對(duì)象代表什么?
文件和目錄路徑名的抽象表示形式。
C:Drivers 這是一個(gè)File對(duì)象
C:DriversLanRealtekReadme.txt 也是File對(duì)象。
一個(gè)File對(duì)象有可能對(duì)應(yīng)的是目錄,也可能是文件 ;File只是一個(gè)路徑名的抽象表示形式; 不能通過File完成文件的讀和寫
1.常用方法1
(1) exists() 方法:判斷當(dāng)前文件是否存在
(2) creatNewFile() 方法:以文件的形式創(chuàng)建出來
(3) mkdir() 方法:以目錄的形式創(chuàng)建出來; 創(chuàng)建多重目錄mkdirs() 方法
(4)獲取當(dāng)前文件的父路徑:
方法1: 使用 getParent() ,返回的是一個(gè) String
方法2:使用 getParentFile()
,返回的是一個(gè)
File
;和上面效果是一樣的
(5) getAbsolutePath() 方法:獲取當(dāng)前文件的絕對(duì)路徑
package com.bjpowernode.java.io;import java.io.File;public class FileTest01 { public static void main(String[] args) throws Exception { // 創(chuàng)建File對(duì)象 File f1 = new File("D:\file"); // 1、判斷當(dāng)前文件是否存在;exists()方法 System.out.println(f1.exists()); // false // 2、如果D:file不存在,則以文件的形式創(chuàng)建出來;createNewFile()方法 if (!f1.exists()) { f1.createNewFile(); } // 3、如果D:file不存在,則以目錄的形式創(chuàng)建出來;mkdir()方法 if (!f1.exists()) { f1.mkdir(); } // 4、創(chuàng)建多重目錄;mkdirs()方法 File f2 = new File("D:/a/b/c/d"); if (!f2.exists()) { f2.mkdirs(); } // 5、獲取當(dāng)前文件的父路徑 File f3 = new File("D:\Python/ target=_blank class=infotextkey>Python學(xué)習(xí)\PyCharm Community Edition 2021.2.2"); // 第一種:使用getParent(),返回的是一個(gè)String String parentPath = f3.getParent(); System.out.println(parentPath); // D:python學(xué)習(xí) // 第二種:使用getParentFile(),返回的是一個(gè)File;效果是一樣的 File parentFile = f3.getParentFile(); System.out.println(parentFile); // D:python學(xué)習(xí) // 6、獲取當(dāng)前文件的絕對(duì)路徑 File f4 = new File("file"); System.out.println(f4.getAbsolutePath()); // C:Users86177IdeaProjectsJavaSe1file }}
2.常用方法2
(1) getName() :獲取當(dāng)前文件的名字
(2) isDirectory() :判斷是否是一個(gè)目錄
(3) isFile() :判斷是否是一個(gè)文件
(4) lastModified() :獲取文件最后一次修改時(shí)間;得到的是毫秒數(shù),返回long型
(5) length() :獲取文件大小,結(jié)果是字節(jié)
package com.bjpowernode.java.io;import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;public class FileTest02 { public static void main(String[] args) { File f1 = new File("C:\Java學(xué)習(xí)\javaSE學(xué)習(xí)\2.1JavaSE進(jìn)階筆記\javase\Copy02.java"); // 1、獲取文件名,getName()方法 System.out.println("文件名:"+f1.getName()); // 文件名:Copy02.java // 2、判斷是否是一個(gè)目錄,isDirectory()方法 System.out.println(f1.isDirectory()); // false // 3、判斷是否是一個(gè)文件,isFile()方法 System.out.println(f1.isFile()); // true // 4、獲取文件最后一次修改時(shí)間,lastModified()方法 // 得到的是毫秒數(shù) long modifytTime = f1.lastModified(); // 將總毫秒數(shù)轉(zhuǎn)換成日期 Date date = new Date(modifytTime); // 格式化 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); System.out.println(sdf.format(date)); //2020-03-11 14:35:46 154 // 5、獲取文件大小,length()方法 System.out.println(f1.length()); //1490 字節(jié) }}
3.listFiles方法
File中的 listFiles方法 ; 獲取當(dāng)前目錄下所有的子文件 ; 返回的是一個(gè)File[]數(shù)組
package com.bjpowernode.java.io;import java.io.File;public class FileTest03 { public static void main(String[] args) { File f = new File("C:\Java學(xué)習(xí)\javaSE學(xué)習(xí)\2.1JavaSE進(jìn)階筆記\javase\chapter15\src"); // 調(diào)用listFiles()方法,返回的是一個(gè)File[]數(shù)組 File[] files = f.listFiles(); // 用增強(qiáng)for循環(huán)打印 for(File file :files){ System.out.println(file.getAbsolutePath()); // 獲取所有子目錄的絕對(duì)路徑 System.out.println(file.getName()); //獲取所有子目錄的文件名 } }}
結(jié)束語
今天的分享就到這里啦!