JAVA IO操作笔记
目錄
- 0 準(zhǔn)備
- 1 文件
- 1.1 文件常用操作
- 1.1.1 創(chuàng)建文件
- 1.1.2 獲取文件信息
- 1.1.3 文件刪除
- 1.1.4 創(chuàng)建目錄
- 2 IO流
- 2.1 原理及分類
- 2.2 常用IO流
- 2.2.1 文件字節(jié)輸入流 FileInputStream
- 2.2.2 文件字節(jié)輸出流 FileOutputStream
- 2.2.3 文件字符輸入流 FileReader
- 2.2.4 文件字符輸出流 FileWriter
- 2.2.5 緩沖字節(jié)輸入流 BufferedInputStream
- 2.2.6 緩沖字節(jié)輸出流 BufferedOutputStream
- 2.2.7 緩沖字符輸入流 BufferedReader
- 2.2.8 緩沖字符輸出流 BufferedWriter
- 2.2.9 對象輸字節(jié)出流 ObjectOutputStream
- 2.2.10 對象字節(jié)輸入流 ObjectInputStream
- 2.2.11 標(biāo)準(zhǔn)輸入輸出流 System.in / System.out
- 2.2.12 轉(zhuǎn)換字符輸入流 InputStreamReader (防止中文亂碼)
- 2.2.13 轉(zhuǎn)換字符輸出流 OutputStreamWriter (防止中文亂碼)
- 2.2.14 字節(jié)打印輸出流 PrintStream
- 2.2.14 字符打印輸出流 PrintWriter
- 2.2.15 配置文件操作 properties
0 準(zhǔn)備
需要的依賴
<dependencies><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>1 文件
文件在程序中以流的形式來操作的,輸入流 與 輸出流 中的 輸入與輸出針對的是內(nèi)存。
File繼承關(guān)系
1.1 文件常用操作
1.1.1 創(chuàng)建文件
/*** 創(chuàng)建文件 方法1* <p>* new File(String pathname)*/@Testpublic void createFile_test01() {// File對象在內(nèi)存中File file = new File("D:\\news1.txt");try {// 內(nèi)存中的File對象寫入磁盤file.createNewFile();System.out.println("文件創(chuàng)建成功");} catch (IOException e) {e.printStackTrace();}}/*** 創(chuàng)建文件 方法2* <p>* new File(File parent,String child)*/@Testpublic void createFile_test02() {File parent = new File("D:\\");String child = "news2.txt";File file = new File(parent, child);try {file.createNewFile();System.out.println("創(chuàng)建成功");} catch (IOException e) {e.printStackTrace();}}/*** 創(chuàng)建文件 方法3* <p>* new File(String parent, String child)*/@Testpublic void createFile_test03() {File file = new File("D:\\", "news3.txt");try {file.createNewFile();System.out.println("創(chuàng)建成功");} catch (IOException e) {e.printStackTrace();}}1.1.2 獲取文件信息
/*** 獲取文件信息*/@Testpublic void getFileInfo_test01() {// 創(chuàng)建文件對象File file = new File("D:\\news1.txt");// 獲取文件名System.out.println(file.getName());// 獲取絕對路徑System.out.println(file.getAbsolutePath());// 獲取文件父級目錄System.out.println(file.getParent());// 獲取文件字節(jié)大小(在utf-8下,一個英文字符是1個字節(jié),一個漢字是3個字節(jié))System.out.println(file.length());// 判斷文件是否存在System.out.println(file.exists());// 是不是一個文件System.out.println(file.isFile());// 是不是一個目錄System.out.println(file.isDirectory());}1.1.3 文件刪除
delete刪除空目錄或文件(delete刪除一個目錄時,需要確保該目錄下面沒有文件或者子目錄,否則需要先刪除文件和字目錄)
/*** 判斷 “d:\\news1.txt” 是否存在,如果存在就刪除*/@Testpublic void deleteFile_test01() {String filePath = "d:\\news1.txt";File file = new File(filePath);if (file.exists()) {if (file.delete()) {System.out.println(filePath + "刪除成功");} else {System.out.println(filePath + "刪除失敗");}} else {System.out.println("該文件不存在...");}}/*** 判斷 “D:\\demo02” 是否存在,存在就刪除,否則提示不存在* <p>* 這里需要體會到,在java編程中,目錄也被當(dāng)做文件*/@Testpublic void deleteFile_test02() {String filePath = "D:\\demo02";File file = new File(filePath);if (file.exists()) {if (file.delete()) {System.out.println(filePath + "刪除成功");} else {System.out.println(filePath + "刪除失敗");}} else {System.out.println("該目錄不存在...");}}1.1.4 創(chuàng)建目錄
mkdir 創(chuàng)建一級目錄
mkdirs 創(chuàng)建多級目錄
2 IO流
2.1 原理及分類
io流簡介
i/o是input/output的縮寫, i/o技術(shù)是非常實用的技術(shù),用于處理設(shè)備之間的數(shù)據(jù)傳輸。如讀/寫文件,網(wǎng)絡(luò)通訊等。
java程序中,對于數(shù)據(jù)的輸入/輸出操作以“流(stream)” 的方式進(jìn)行。
java.io包下提供了各種“流”類和接口,用以獲取不同種類的數(shù)據(jù),并通過標(biāo)準(zhǔn)的方法輸入或輸出數(shù)據(jù)。
io流原理
輸入input:讀取外部數(shù)據(jù)(磁盤、光盤等存儲設(shè)備的數(shù)據(jù))到程序(內(nèi)存)中。
輸出output:將程序(內(nèi)存)數(shù)據(jù)輸出到磁盤、光盤等存儲設(shè)備中。
流的分類
(1) 輸入輸出流
按照流的流向分為輸入流和輸出流。是以內(nèi)存的角度來劃分。
輸入流: 只能讀取數(shù)據(jù),不能寫入。由InputStream 和 Reader作為基類;
輸出流: 只能寫入數(shù)據(jù),不能讀取。由OutputStream 和 Writer 作為基類;
(2) 字節(jié)流和字符流
字節(jié)流:操作數(shù)據(jù)單元為 8 位字節(jié),由 InputStream 和 OutputStream作為基類;
字符流:操作數(shù)據(jù)單元為16位字符,由 Reader 和 Writer 作為基類;
(3) 節(jié)點流和處理流
按角色分為節(jié)點流和處理流。
節(jié)點流:從一個特定的IO設(shè)備(磁盤,或網(wǎng)絡(luò))讀寫數(shù)據(jù)的流,稱為。
包裝流:也叫處理流,對節(jié)點流的封裝,提供更豐富的功能與更好的性能。
使用裝飾器設(shè)計模式。
四個基本抽象類
均為抽象類,都需要調(diào)用他們的實現(xiàn)子類創(chuàng)建。
基于以上四個抽象類,根據(jù)各種業(yè)務(wù)場景的需要衍生出如下IO流操作相關(guān)類
使用注意事項:
2.2 常用IO流
2.2.1 文件字節(jié)輸入流 FileInputStream
read() 方法是一個一個字節(jié)去讀取,中文一個占三個字節(jié),故會出現(xiàn)亂碼,并且效率極低
/*** 方法:* public int read() throws IOException* 從該輸入流讀取一個字節(jié)的數(shù)據(jù)。 如果沒有輸入可用,此方法將阻止。* <p>* 結(jié)果:* 數(shù)據(jù)的下一個字節(jié),如果達(dá)到文件的末尾,-1。* <p>* 注意:* 一個中文大于一個字節(jié),中文一定會很亂碼。*/@Testpublic void test_read() {String filePath = "src\\main\\resources\\fileInputStream";int readData = 0;InputStream inputStream = null;try {inputStream = new FileInputStream(filePath);while ((readData = inputStream.read()) != -1) {System.out.print((char) readData); // 轉(zhuǎn)換成char顯示}} catch (Exception e) {e.printStackTrace();} finally {// 一定要關(guān)閉文件流,釋放資源IOUtils.closeQuietly(inputStream);}}一般使用的是 read(byte[] byte) 。一次性讀取一個指定長度的字節(jié)
/*** 方法:* public int read(byte[] b) throws IOException* 從該輸入流讀取最多b.length字節(jié)的數(shù)據(jù)到字節(jié)數(shù)組。 此方法將阻塞,直到某些輸入可用。* <p>* 參數(shù):* b - 讀取數(shù)據(jù)的緩沖區(qū)。取值合理不會出現(xiàn)中文亂碼* <p>* 結(jié)果:* 讀入緩沖區(qū)的總字節(jié)數(shù),如果沒有更多的數(shù)據(jù),因為文件的結(jié)尾已經(jīng)到達(dá), -1 。*/@Testpublic void test_read_bytes() {String filePath = "src\\main\\resources\\fileInputStream";int readLen = 0;// bytes 取值為中文字符的整數(shù)倍則不會中文亂碼byte[] bytes = new byte[3];InputStream inputStream = null;try {inputStream = new FileInputStream(filePath);while ((readLen = inputStream.read(bytes)) != -1) {// 注意最后一次讀取時,bytes不滿的情況下,后邊不滿的幾位會緩存上次循環(huán)的數(shù)據(jù)System.out.print(new String(bytes, 0, readLen));}} catch (Exception e) {e.printStackTrace();} finally {// 一定要關(guān)閉文件流,釋放資源IOUtils.closeQuietly(inputStream);}}2.2.2 文件字節(jié)輸出流 FileOutputStream
/*** 使用FileOutputStream 在a.txt文件,中寫入"hello, world"* 對于FileOutputStream,如果文件不存在,會創(chuàng)建文件(注意:前提是目錄已經(jīng)存在)*/@Testpublic void test_write() {// 創(chuàng)建 FileOutputStream對象String filePath = "src\\main\\resources\\a.txt";FileOutputStream fileOutputStream = null;try {// 1. new FileOutputStream(filePath) 創(chuàng)建方式,當(dāng)寫入內(nèi)容時,會覆蓋原來的內(nèi)容。// 2. new FileOutputStream(filePath, true) 創(chuàng)建方式,當(dāng)寫入內(nèi)容是,是追加到文件后面。fileOutputStream = new FileOutputStream(filePath, true);// 寫入一個字節(jié)fileOutputStream.write('H');// 寫入字符串(字符串-> 字節(jié)數(shù)組)String str = "hello,world!";fileOutputStream.write(str.getBytes());// 截取字符串一部分進(jìn)行寫入 [0,5)fileOutputStream.write(str.getBytes(), 0, 5);} catch (IOException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(fileOutputStream);}} /*** 文件拷貝*/@Testpublic void fileCopy() {String inputFilePath = "src\\main\\resources\\王者榮耀.jpg";String outFilePath = "src\\main\\resources\\王者榮耀_copy.jpg";FileOutputStream fileOutputStream = null;FileInputStream fileInputStream = null;byte[] buf = new byte[1024];int readLength = 0;try {fileInputStream = new FileInputStream(inputFilePath);fileOutputStream = new FileOutputStream(outFilePath, true);while ((readLength = fileInputStream.read(buf)) != -1) {// 注意:一定要使用這個方法,防止buf緩存倒數(shù)第二次結(jié)果,可能造成文件損壞fileOutputStream.write(buf, 0, readLength);}System.out.println("文件拷貝成功");} catch (Exception e) {e.printStackTrace();} finally {// 注意先關(guān)閉輸入流,在關(guān)閉輸出流IOUtils.closeQuietly(fileInputStream, fileOutputStream);}}2.2.3 文件字符輸入流 FileReader
可以處理中文字符
/*** 單個字符讀取文件(效率很低)*/@Testpublic void readFile01() {String filePath = "src\\main\\resources\\a.txt";FileReader fileReader = null;int data = 0;try {fileReader = new FileReader(filePath);// 循環(huán)讀取 使用read, 單個字符讀取while ((data = fileReader.read()) != -1) {System.out.print((char) data);}} catch (IOException e) {e.printStackTrace();} finally {// 一定要關(guān)閉文件流,釋放資源IOUtils.closeQuietly(fileReader);}}/*** 字符數(shù)組讀取文件*/@Testpublic void readFile02() {String filePath = "src\\main\\resources\\a.txt";FileReader fileReader = null;int readLen = 0;char[] buf = new char[8];try {fileReader = new FileReader(filePath);// 循環(huán)讀取使用read(buf), 返回的數(shù)據(jù)緩存在字符數(shù)組buf// 如果返回-1, 說明到文件結(jié)束while ((readLen = fileReader.read(buf)) != -1) {System.out.print(new String(buf, 0, readLen));}} catch (IOException e) {e.printStackTrace();} finally {// 一定要關(guān)閉文件流,釋放資源IOUtils.closeQuietly(fileReader);}}2.2.4 文件字符輸出流 FileWriter
使用FileWriter時 flush()或close必須執(zhí)行期其中一個,不然無法寫入文件
@Testpublic void write_Test() {String filePath = "src\\main\\resources\\b.txt";FileWriter fileWriter = null;try {// 覆蓋方式// fileWriter = new FileWriter(filePath);// 追加方式fileWriter = new FileWriter(filePath, true);// 1. write(int) 寫入單個字符fileWriter.write('H');// 2. write(char[]): 寫入字符數(shù)組char[] chars = {'a', 'b', 'c'};fileWriter.write(chars);// 默認(rèn)是覆蓋// 3. write(char[],off,len): 寫入字符數(shù)組的截取部分fileWriter.write("李淳罡--陸地神仙境".toCharArray(), 0, 3);// 4. write(String) :寫入整個字符串fileWriter.write("你好啊北京");// 5. write(string,off,len):寫入字符串的截取部分fileWriter.write("李白--詩仙", 0, 2);// 在數(shù)據(jù)量比較大的時候采用循環(huán)才做// 注意:flush()或close() 必須執(zhí)行期其中一個,否則不會輸出到文件// 因為實際寫出到文件的操作在這兩個方法中被調(diào)用fileWriter.flush();System.out.println("文件輸出成功");} catch (Exception e) {e.printStackTrace();} finally {// 一定要關(guān)閉文件流,釋放資源IOUtils.closeQuietly(fileWriter);}}2.2.5 緩沖字節(jié)輸入流 BufferedInputStream
@Testpublic void test_readLine() {String filePath = "src\\main\\resources\\a.txt";int readLen = 0;byte[] buf = new byte[1024]; // 取值為中文字符的整數(shù)倍則不會中文亂碼BufferedInputStream bufferedInputStream = null;try {bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));while ((readLen = bufferedInputStream.read(buf)) != -1) {System.out.println(new String(buf, 0, readLen));}} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedInputStream);}}2.2.6 緩沖字節(jié)輸出流 BufferedOutputStream
@Testpublic void test_copy() {String inputFilePath = "src\\main\\resources\\王者榮耀.jpg";String outputFilePath = "src\\main\\resources\\王者榮耀_copy1.jpg";byte[] buf = new byte[1024];int readLen;BufferedInputStream bufferedInputStream = null;BufferedOutputStream bufferedOutputStream = null;try {bufferedInputStream = new BufferedInputStream(new FileInputStream(inputFilePath));bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputFilePath));while ((readLen = bufferedInputStream.read(buf)) != -1) {// 注意:一定要使用這個方法,防止buf緩存倒數(shù)第二次結(jié)果,可能造成文件損壞bufferedOutputStream.write(buf, 0, readLen);}} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedInputStream, bufferedOutputStream);}}2.2.7 緩沖字符輸入流 BufferedReader
BufferedReader屬于字符流,是按照字符讀取數(shù)據(jù)的,所以最好處理文本文件,像圖片,聲音這種字節(jié)組織的二進(jìn)制文件的話,用字符流讀取可能會造成文件損失,所以最好使用字節(jié)流。
@Testpublic void test_readLine() {String filePath = "src\\main\\resources\\a.txt";BufferedReader bufferedReader = null;try {// 創(chuàng)建 BufferedReaderbufferedReader = new BufferedReader(new FileReader(filePath));// 按行讀取,效率高String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedReader);}}2.2.8 緩沖字符輸出流 BufferedWriter
BufferedWriter屬于字符流,是按照字符讀取數(shù)據(jù)的,所以最好處理文本文件,像圖片,聲音這種字節(jié)組織的二進(jìn)制文件的話,用字符流讀取可能會造成文件損失,所以最好使用字節(jié)流。
@Testpublic void test_write() {String filePath = "src\\main\\resources\\d.txt";BufferedWriter bufferedWriter = null;try {// 覆蓋的方式// bufferedWriter = new BufferedWriter(new FileWriter(filePath));// 追加的方式bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));for (int i = 0; i < 3; i++) {bufferedWriter.write("你好啊,boy!");bufferedWriter.newLine();bufferedWriter.write("你好啊,小胖子!");bufferedWriter.write("你好啊,girls!");// 注意:flush()或close() 必須執(zhí)行期其中一個,否則不會輸出到文件// 因為實際寫出到文件的操作在這兩個方法中被調(diào)用bufferedWriter.flush();}System.out.println("寫出完成");} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedWriter);}} /*** 文件拷貝* <p>* 不要去操作 二進(jìn)制文件[聲音,視頻,doc, pdf 等], 可能造成文件損壞!!*/@Testpublic void test_copy() {String inputFilePath = "src\\main\\resources\\a.txt";String outputFilePath = "src\\main\\resources\\a_copy.txt";BufferedWriter bufferedWriter = null;BufferedReader bufferedReader = null;try {bufferedReader = new BufferedReader(new FileReader(inputFilePath));bufferedWriter = new BufferedWriter(new FileWriter(outputFilePath));String readLine;while ((readLine = bufferedReader.readLine()) != null) {bufferedWriter.write(readLine);// readLine讀取一行的時候沒有讀取換行符bufferedWriter.newLine();}System.out.println("完成拷貝...");} catch (IOException e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedReader, bufferedWriter);}}2.2.9 對象輸字節(jié)出流 ObjectOutputStream
將 java對象 序列化后輸出到文件(要求 java對象支持序列化)
public class Dog implements Serializable {private String name;private int age;public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';} } /*** 序列化輸出到文件*/@Testpublic void test() {// 序列化之后,保存的文件格式,不是存文本,而是按照他的格式來保存String filePath = "src\\main\\resources\\dog.dat";ObjectOutputStream objectOutputStream = null;try {objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));objectOutputStream.writeInt(100); // int -> Integer (實現(xiàn)了 Serializable)objectOutputStream.writeBoolean(true); // boolean -> Boolean (實現(xiàn)了 Serializable)objectOutputStream.writeChar('a'); // char -> Character (實現(xiàn)了 Serializable)objectOutputStream.writeDouble(9.5); // double -> Double (實現(xiàn)了 Serializable)objectOutputStream.writeUTF("莫寒寒來咯!"); // String (實現(xiàn)了 Serializable)objectOutputStream.writeObject(new Dog("旺財", 10)); // Dog (實現(xiàn)了 Serializable)System.out.println("序列化輸出成功...");} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(objectOutputStream);}}2.2.10 對象字節(jié)輸入流 ObjectInputStream
將文件中的數(shù)據(jù)讀取并反序列化為 java對象 (要求 java對象支持序列化)
/*** 序列化輸出到文件*/@Testpublic void test() {String filePath = "src\\main\\resources\\dog.dat";ObjectInputStream objectInputStream = null;try {objectInputStream = new ObjectInputStream(new FileInputStream(filePath));// 注意:讀取反序列化的順序需要和保存數(shù)據(jù)序列化的順序一致,否則會出異常System.out.println(objectInputStream.readInt());System.out.println(objectInputStream.readBoolean());System.out.println(objectInputStream.readChar());System.out.println(objectInputStream.readDouble());System.out.println(objectInputStream.readUTF());Object dog = objectInputStream.readObject();Dog dog1 = (Dog) dog;System.out.println(dog1);} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(objectInputStream);}}對象處理流使用細(xì)節(jié)
2.2.11 標(biāo)準(zhǔn)輸入輸出流 System.in / System.out
public static void main(String[] args) {// System.in 編譯類型 InputStream// System.in 運(yùn)行類型 BufferedInputStream// 表示標(biāo)準(zhǔn)輸入--鍵盤System.out.println(System.in.getClass());// System.out 編譯類型 PrintStream// System.out 運(yùn)行類型 PrintStream// 表示標(biāo)準(zhǔn)輸出--顯示器System.out.println(System.out.getClass());Scanner scanner = new Scanner(System.in);System.out.println("輸入內(nèi)容");String next = scanner.next();System.out.println("next=" + next);}2.2.12 轉(zhuǎn)換字符輸入流 InputStreamReader (防止中文亂碼)
轉(zhuǎn)換流可以將字節(jié)流轉(zhuǎn)換成字符流
字符編碼不統(tǒng)一導(dǎo)致的中文亂碼問題
/*** 測試編碼導(dǎo)致的 "中文亂碼" 問題*/@Testpublic void test_code_question() {//思路//1. 創(chuàng)建字符輸入流 BufferedReader [處理流]//2. 使用 BufferedReader 對象讀取文件//3. 默認(rèn)情況下,讀取文件是按照 utf-8 編碼String filePath = "src\\main\\resources\\a_gbk.txt";BufferedReader bufferedReader = null;try {// 創(chuàng)建 BufferedReaderbufferedReader = new BufferedReader(new FileReader(filePath));// 按行讀取,效率高String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedReader);}}文件采用 gbk 的編碼方式,內(nèi)容如下:
因為編碼問題到導(dǎo)致的亂碼結(jié)果
采用轉(zhuǎn)換流解決中文亂碼問題
/*** 使用 InputStreamReader 轉(zhuǎn)換流解決中文亂碼問題* 將字節(jié)流 FileInputStream 轉(zhuǎn)成字符流 InputStreamReader, 指定編碼 gbk*/@Testpublic void test_read_code() {String filePath = "src\\main\\resources\\a_gbk.txt";BufferedReader bufferedReader = null;try {// 把 FileInputStream 轉(zhuǎn)成 InputStreamReader,并指定編碼 gbkInputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), "gbk");// 使用緩沖流,按行讀取,效率高(可以不使用)bufferedReader = new BufferedReader(inputStreamReader);String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();} finally {// 關(guān)閉最外層的裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedReader);}}轉(zhuǎn)換流指定的編碼格式必須和文本編碼一致,否則會中文亂碼
2.2.13 轉(zhuǎn)換字符輸出流 OutputStreamWriter (防止中文亂碼)
轉(zhuǎn)換流可以將字節(jié)流轉(zhuǎn)換成字符流
/*** 使用 OutputStreamWriter 轉(zhuǎn)換流解決中文亂碼問題* 將字節(jié)流 FileOutputStream 轉(zhuǎn)成字符流 OutputStreamWriter, 指定編碼 gbk*/@Testpublic void test_write_code() {String filePath = "src\\main\\resources\\gbk.txt";BufferedWriter bufferedWriter = null;try {// 把 FileOutputStream 轉(zhuǎn)成 OutputStreamWriter,并指定編碼 gbkOutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filePath), "gbk");// 使用緩沖流,按行讀取,效率高(可以不使用)bufferedWriter = new BufferedWriter(outputStreamWriter);bufferedWriter.write("hi");bufferedWriter.newLine();bufferedWriter.write("hello,world!");bufferedWriter.newLine();bufferedWriter.write("中國浙江杭州");bufferedWriter.newLine();} catch (IOException e) {e.printStackTrace();} finally {// 關(guān)閉最外層的裝飾流,實際會關(guān)閉其內(nèi)部持有的節(jié)點流IOUtils.closeQuietly(bufferedWriter);}}2.2.14 字節(jié)打印輸出流 PrintStream
打印流只有輸出流沒有輸入流
/*** 演示PrintStream (字節(jié)打印流/輸出流)*/@Testpublic void test_write() throws IOException {String filePath = "src\\main\\resources\\PrintStream.txt";PrintStream out = System.out;// 在默認(rèn)情況下,PrintStream 輸出數(shù)據(jù)的位置是 標(biāo)準(zhǔn)輸出,即顯示器out.print(" hello ");// 因為print底層使用的是write , 所以我們可以直接調(diào)用write進(jìn)行打印/輸出out.write(" 你好 ".getBytes());// 可以去修改打印流輸出的 位置/設(shè)備System.setOut(new PrintStream(filePath));System.out.println("hello, PrintStream~");out.close();}2.2.14 字符打印輸出流 PrintWriter
打印流只有輸出流沒有輸入流
/*** 演示 PrintWriter 使用方式*/@Testpublic void test_write() throws IOException {String filePath = "src\\main\\resources\\PrintWriter.txt";// 寫到控制臺// PrintWriter printWriter = new PrintWriter(System.out);// 寫入文件PrintWriter printWriter = new PrintWriter(new FileWriter(filePath));printWriter.print("hi, 你好~~~~");// 注意:flush()或close必須執(zhí)行期其中一個,否則不會輸出到文件printWriter.close();}2.2.15 配置文件操作 properties
/*** 讀取 properties 配置文件*/@Testpublic void test_read() throws IOException {String filePath = "src\\main\\resources\\mysql.properties";// 1. 創(chuàng)建一個Properties對象Properties properties = new Properties();// 2. 加載指定配置文件properties.load(new FileReader(filePath));// 3. 把k-v顯示到控制臺properties.list(System.out);// 4. 根據(jù)key 獲取對應(yīng)的值String username = properties.getProperty("username");System.out.println("username=" + username);String password = properties.getProperty("password");System.out.println("password=" + password);}/*** 寫入 properties 配置文件*/@Testpublic void test_write() throws IOException {String filePath = "src\\main\\resources\\mysql.properties";// 使用Properties類來創(chuàng)建配置文件, 修改配置文件的內(nèi)容Properties properties = new Properties();properties.setProperty("charset", "utf8");properties.setProperty("user", "小明");// 底層是個hashTable,不允許重復(fù),如果存在,則替換。properties.setProperty("user", "小紅");properties.store(new FileOutputStream(filePath), "hello world");System.out.println("保存文件成功");}總結(jié)
以上是生活随笔為你收集整理的JAVA IO操作笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第11章:图像金字塔
- 下一篇: Debian安装docker全流程