輸入輸出的重要性:
輸入和輸出功能是Java對程序處理數據能力的提高,Java以流的形式處理數據。流是一組有序的數據序列,根據操作的類型,分為輸入流和輸出流。
程序從輸入流讀取數據,向輸出流寫入數據。Java是面向對象的程序語言,每一個數據流都是一個對象,它們提供了各種支持“讀入”與“寫入”操作的流類。
Java的輸入輸出功能來自java.io 包中的InputStream類、OutputStream類、Reader類和Writer類以及繼承它們的各種子類。
(一)解析文件處理的奧秘
1、學習使用文件類 : File類
File類用於封裝系統的文件和目錄的相關信息。在該類中定義了一些與平台無關的方法來操作文件。例如文件的大小、修改時間、文件路徑等。
創建 File 對象可以通過下面3種方式:
方法1: | 方法2: | 方法3: |
---|---|---|
new File(String pathName) | File file = new File(“E://1.txt”) | new File(String parent , String child) |
parent :父抽象路徑名;child:子路徑名字符串 |
2、如何獲取文件信息
File 類是對文件和文件夾的抽象,包含了對文件和文件夾的多種屬性和操作方法。File類的常用方法如下表:
返回 | 方法 | 說明 |
---|---|---|
String | getName | 獲取文件名稱 |
String | getParent | 獲取文件的父路徑字符串 |
String | getPath | 獲取文件的相對路徑字符串 |
String | getAbsolutePath | 獲取文件的絕對路徑字符串 |
boolean | exists | 判斷文件或者文件夾是否存在 |
boolean | isFile | 判斷是不是文件類型 |
boolean | isDirectory | 判斷是不是文件夾類型 |
boolean | delete | 刪除文件或文件夾,如果刪除成功返回結果為true |
boolean | mkdir | 創建文件夾,創建成功返回true |
boolean | setReadOnly | 設置文件或文件夾的只讀屬性 |
long | length | 獲取文件的長度 |
long | lastModified | 獲取文件的最后修改時間 |
String[ ] | list | 獲取文件夾中的文件和子文件夾的名稱,並存放到字符串數組中 |
下面通過實例介紹File類獲取文件信息
1 package com.zch.io; 2 3 import java.io.File; 4 import java.util.Date; 5 6 /** 7 * 在src根目錄下創建FileInfo類,在該類的主方法中創建文件對象,通過File類的相關方法,獲取文件的相關信息 8 * 9 * @author zch 10 * 11 */ 12 public class FileInfo { 13 public static void main(String[] args) { 14 15 String filePath = "src/com/zch/io/FileInfo.java"; 16 // 根據指定路徑創建文件對象 17 File file = new File(filePath); 18 System.out.println("文件名稱:" + file.getName()); 19 System.out.println("文件是否存在:" + file.exists()); 20 System.out.println("文件的相對路徑:" + file.getPath()); 21 System.out.println("文件的絕對路徑:" + file.getAbsolutePath()); 22 System.out.println("是否為可執行文件:" + file.canExecute()); 23 System.out.println("文件可以讀取:" + file.canRead()); 24 System.out.println("文件可以寫入:" + file.canWrite()); 25 System.out.println("文件上級路徑:" + file.getParent()); 26 System.out.println("文件大小:" + file.length() + "B"); 27 System.out.println("文件最后修改時間:" + new Date(file.lastModified())); 28 System.out.println("是否文件類型:" + file.isFile()); 29 System.out.println("是否為文件夾:" + file.isDirectory()); 30 31 } 32 33 }
運行結果如下:
文件名稱:FileInfo.java 文件是否存在:true 文件的相對路徑:src\com\zch\io\FileInfo.java 文件的絕對路徑:D:\Java\IO\src\com\zch\io\FileInfo.java 是否為可執行文件:true 文件可以讀取:true 文件可以寫入:true 文件上級路徑:src\com\zch\io 文件大小:1195B 文件最后修改時間:Sat Sep 09 21:30:10 CST 2017 是否文件類型:true 是否為文件夾:false
在使用delete()方法刪除File對象時,如果刪除的對象是目錄,該目錄中的內容必須為空。
(二)使用字節輸入輸出流
字節流用於處理二進制數據的讀取和寫入,它以字節為單位,InputStream類和OutputStream類是字節流的抽象類,它們定義了數據流讀取和寫入的基本方法。各個子類會依其特點實現或覆蓋這些方法。
1、字節數入流抽象類InputStream
InputStream 類是字節輸入流的抽象類,定義了操作輸入流的各種方法,這些方法如表:
返回 | 方法 | 說明 |
---|---|---|
int | available() | 返回當前輸入流的數據讀取方法可以讀取的有效字節數量 |
Abstract int | read() | 從當前數據流中讀取一個字節。若已達到流結尾,則返回-1 |
int | read(byte[ ] bytes) | 從當前輸入流讀取一定的byte數據,並存取在數組中,然后返回讀取的byte數據的數量,若已到達流結尾,則返回-1。 |
void | reset() | 將當前的輸入流重新定位到最后一次調用mark()方法時的位置 |
void | mark(int readlimit) | 在當前輸入流中做標記位置,當調用reset()方法時將返回到該位置,從標記位置開始,到再讀入readlimit個字符為止,這個標記都維持有效。 |
Boolean | markSupported() | 測試當前輸入流是否支持mark()和reset()方法,只要其中一個不支持,則返回false |
long | skip(long n) | 跳過和丟棄當前輸入的n個字節數據 |
void | close() | 關閉當前輸入流,並釋放任何與之相關聯的系統資源 |
InputStream 類是抽象類,不能通過new關鍵字來創建該實例對象,需要其子類創建該實例對象。下面通過實例如何使用InputStream從控制台獲取用戶輸入的數據信息。
1 package com.zch.io; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 /** 7 * 創建InputStream實例inp,並將其賦值為System類的in屬性,定義為控制台輸入流,從inp輸入流中獲取字節信息, 8 * 用這些字節信息創建字符串,並將其在控制台上輸出。 9 * @author zch 10 * 11 */ 12 public class InputMessage { 13 public static void main(String[] args) { 14 InputStream inp = System.in; 15 16 byte[] bytes = new byte[1024]; 17 18 try { 19 while(inp.read() != -1){ 20 //根據用戶輸入的信息創建字符串 21 22 String str = new String(bytes).trim(); 23 24 } 25 inp.close(); //關閉流 26 27 } catch (IOException e) { 28 // TODO Auto-generated catch block 29 e.printStackTrace(); 30 } 31 32 } 33 } 34
2、字節輸出流抽象類OutputStream類
OutputStream定義了輸出流的各種方法,如下表:
返回 | 方法 | 說明 |
---|---|---|
void | write(byte[ ] b) | 將byte[ ] 數組中的數據寫入當前輸出流 |
void | write(byte[] b ,int off, int len) | 將byte[ ]數組下標off開始的len長度的數據寫入當前輸出流 |
Abstract void | write(int b) | 寫入一個byte數據到當前輸出流 |
void | flush() | 刷新當前輸出流,並強制寫入所有緩沖的字節數據 |
void | close() | 關閉當前輸出流 |
和InputStream類一樣,OutputStream 類是抽象類,不能通過new關鍵字來創建該實例對象,需要其子類創建該實例對象。
package com.zch.io; import java.io.IOException; import java.io.OutputStream; /** * 創建OutputStream實例out,並將其賦值為System.out標准輸出流。通過write()方法向流寫入數據。 * @author zch * */ public class OutputData { public static void main(String[] args) { OutputStream output = System.out; //實例化OutputStream對象 byte[] bytes = "使用OutputStream輸出流在控制台輸出字符串\n".getBytes(); //創建bytes數組 try { output.write(bytes); bytes = "輸出內容:\n".getBytes(); output.write(bytes); //向流中寫入數據 bytes = "Java數據交互管道——IO流 \n".getBytes(); output.write(bytes); output.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
輸出結果如下:
使用OutputStream輸出流在控制台輸出字符串 輸出內容: Java數據交互管道——IO流
3、文件字節輸入流類 : FileInputStream類
文件字節輸入流可以從指定路徑的文件中讀取字節數據。文件字節輸入流類繼承InputStream類,並實現了讀取輸入流的各種方法。
創建文件字節輸入流創建的構造方法語法如下:
- 語法1:以File對象為參數創建FileInputStream實例
new FileInputStream(File file)
- 語法2:以文件對象的絕對路徑為參數創建FIleInputStream實例
new FileInputStream(String filepath)
4、文件字節輸出流類:FileOutputStream
文件字節輸出流關聯指定文件路徑的文件,數據通過文件字節輸出流以字節為單位輸出並保存到文件中。文件字節輸出流繼承自OutputStream類,並實現OutputStream類的各種方法。
文件字節輸出流的構造方法語法如下:
- 語法1:以File對象為參數創建FileOutputStream實例
new FileOutputStream(File file)
- 語法2:以文件對象的絕對路徑為參數創建FIleOutputStream實例
new FileOutputStream(String filepath)
下面通過實例介紹文件的寫入和讀取:
package com.zch.io; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * 創建OutputStream實例out,並將其賦值為System.out標准輸出流,通過write方法向流中寫入數據 * * @author zch * */ public class FileCreate { public static void main(String[] args) { File file = new File("D:/", "word.txt"); //創建文件對象 try { if (!file.exists()) { //如果文件不存在則新建文件 file.createNewFile(); } FileOutputStream output = new FileOutputStream(file); byte[] bytes = "Java數據交流管道——IO流".getBytes(); output.write(bytes); //將數組的信息寫入文件中 output.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { FileInputStream input = new FileInputStream(file); byte[] bytes2 = new byte[1024]; int len = input.read(bytes2); System.out.println("文件中的信息是:" + new String(bytes2, 0, len)); input.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(三) 使用字符輸入輸出流
字符輸入輸出流 與 字節輸入輸出流有相同的功能,但傳送數據的方式不一樣,字節流以字節為單位傳送數據,可以使任何類型的數據,例如文本、音頻、視頻、圖片等。字符流以字符為單位傳送數據,只能傳送文本類型的數據。使用字符輸入輸出流的好處是,當讀取中文時不會出現亂碼問題,而使用字節輸入輸出流時,卻不能保證這一點。
1、字符輸入流抽象類:Reader類
該類定義了操作字符輸入流的方法,如下表:
返回 | 方法 | 說明 |
---|---|---|
boolean | ready() | 判斷此數據流是否准備好 |
int | read() | 讀入一個字符,若已讀到流結尾,則返回值為-1 |
int | read(char[ ]) | 讀取一些字符到char[ ]數組內,並返回所讀入的字符的數量,若已到達流結尾,則返回-1 |
Abscract int | read(char[ ] chars,int off,int len) | 讀取一些字符到char[ ]數組下標從off開始到off+len的位置,並返回所讀入的字符的數量,若已到達流結尾,則返回-1; |
void | reset() | 將當前輸入流重新定位到最后一次mark()方法時的位置 |
void | mark(int readLimit) | 將當前輸入流中做標記,當調用reset方法時將返回到該位置,從標記位置開始,到再讀入readLimit個字符為止,這個標記都維持有效 |
boolean | markSupported | 測試當前輸入流是否支持mark()方法和reset()方法。只要有一個方法不支持,則返回-1 |
long | skip(long n) | 跳過參數n指定的字符數量,並返回所跳過字符的數量 |
Abstract void | close() | 關閉字符輸入流,並釋放與之關聯的所有資源 |
2、字符輸出流類Writer類
Writer 類主要是用於解決字符輸入流的類,其地位與Reader類在輸入流的地位和作用是相同的,也是所有字符輸出流的流類。
Writer類的主要方法如下:
返回 | 方法 | 說明 |
void | write(char[ ] cbuf) | 將字符數組的數據寫入字符輸出流 |
Abstract void | write(char[ ] cbuf int off ,int len) | 將字符數組從下標off 開始向輸入流寫入長度為len的數據 |
void | write(int c ) | 向字符輸入流中寫入一個字符數據 |
void | write(String str ) | 向輸入流中寫入一個字符串數據 |
void | write(String str , int off ,int len) | 向輸入流中寫入一個字符串從off 開始長度為len的數據 |
Abstract void | flush() | 刷新當前輸出流,並強制寫入所有緩沖區的字節數據 |
void | close() | 向輸出流中寫入緩沖區的數據,然后關閉當前輸出流,釋放所有與當前輸出流相關聯的系統資源 |
3、文件字符輸入流FileReader
文件字符輸入流與文件字節輸入流的功能相似,但是傳送數據的方式不一樣,字節流以字節為單位傳送數據,可以使文本、視頻、音頻、圖片等。字符流以字符為單位傳送數據,只能傳送文本類型的數據。
創建字符輸入流常用的構造方法:
- 語法1:
new FileReader(File file);
- 語法2:
new FileReader(String path);
下面通過實例介紹FileReader類讀取指定磁盤文件的內容。
package com.zch.io; import java.io.File; import java.io.FileReader; public class FileInAndOut { public static void main(String[] args) { //定義指定磁盤的文件的File對象 File file = new File("D://word.txt"); if(! file.exists()){ System.out.println("對不起,不包含指定路徑的文件"); }else{ //根據指定路徑的File對象創建FileReader對象 try { FileReader fr = new FileReader(file); char[] data = new char[23]; //定義char數組 int length = 0; while((length = fr.read(data))>0){ //循環讀取文件中的數據 String str = new String(data,0,length); //根據讀取文件的內容創建String 對象 System.out.println(str); //輸出讀取內容 } fr.close(); //關閉流 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
運行結果如下圖:
4、文件字符輸出流FileWriter
文件字符輸出流繼承自Writer類,提供了向文件輸出的各種方法,數據通過文件字符輸出流以字符為單位輸出並保存到文件中。
package com.zch.io; /** * 通過給定的String類型參數的指定文件名稱與路徑,創建FileWriter類。 * * @author zch */ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo { public static void main(String[] args) { File file = new File("D://word2.txt"); //創建指定文件 try { if(! file.exists()){ file.createNewFile(); //如果指定文件不存在,新建文件 } FileReader fr = new FileReader("D://word.txt"); FileWriter fw = new FileWriter(file); //創建FileWriter對象 int length = 0; while((length = fr.read()) != -1){ //如果沒有讀到文件末尾 fw.write(length); //向文件寫入數據 } fr.close(); //關閉流 fw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
運行后創建了Word2.txt 文件,並向其中寫入數據
(四)IO流實戰:
1、Java IO流實現復制文件夾
通過IO不僅可以復制文件,還可以復制文件夾,但是文件夾內,可能包含其他文件夾,因此需要對他們進行分別復制。
1 package com.zch.io; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 7 public class CopyFile { 8 public static void main(String[] args) { 9 File sourceFile = null; 10 File desFile = null; 11 12 String sourceFolder = "D://簡歷2"; 13 String copyFolder = "D://copy"; 14 15 sourceFile = new File(sourceFolder); 16 17 if (!sourceFile.isDirectory() || !sourceFile.exists()) { 18 System.out.println("源文件夾不存在!"); 19 } else { 20 desFile = new File(copyFolder); 21 desFile.mkdir(); 22 23 copy(sourceFile.listFiles(), desFile); 24 System.out.println("文件夾復制成功!"); 25 } 26 } 27 /** 28 * 創建copy方法,該方法接收文件數組和目標文件夾兩個參數,如果目標文件夾不存在,則調用mkdir()方法創建文件夾,然后再循環中將文件數組 29 * 中的每個文件對象寫到目標文件夾內。 30 * @param fl 31 * @param file 32 */ 33 public static void copy(File[] fl, File file) { 34 if (!file.exists()) { // 如果文件夾不存在 35 file.mkdir(); // 建立新的文件夾 36 } 37 38 for (int i = 0; i < fl.length; i++) { 39 if (fl[i].isFile()) { // 如果是文件類型,則復制文件 40 try { 41 FileInputStream fis = new FileInputStream(fl[i]); 42 FileOutputStream out = new FileOutputStream(new File( 43 file.getPath() + File.separator + fl[i].getName())); 44 45 int count = fis.available(); 46 byte[] data = new byte[count]; 47 48 if ((fis.read(data)) != -1) { 49 out.write(data); 50 } 51 } catch (Exception e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } 55 } 56 57 if (fl[i].isDirectory()) { // 如果是文件夾類型 58 File des = new File(file.getPath() + File.separator 59 + fl[i].getName()); 60 des.mkdir(); // 在目標文件夾中創建相同的文件夾 61 copy(fl[i].listFiles(), des); // 遞歸調用方法本身 62 } 63 64 } 65 66 } 67 }
運行本實例,會將D盤中的簡歷文件中的內容復制到D盤的copy文件夾中,而且包含文件夾的子文件夾
2、Java IO流實現分行向文件中寫入數據
FileWriter類可以向文件寫入字符數據,如果將FileWriter類封裝到BufferWriter類的緩沖字符流中,能夠實現緩沖字符輸出流,並且可以通過讀輸出流的newLine()方法,來實現數據的分行寫入。
1 package com.zch.io; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 8 /** 9 * 創建BranchWriter類,在主方法中定義文件對象,將該對象作為參數創建BufferedWriter類實例, 10 * 調用該實例的writer方法將數據寫入文件中,然后 調用newLine()方法寫入換行符,實現分行向文件寫入數據。 11 * 12 * @author zch 13 * 14 */ 15 public class BranchWriter { 16 public static void main(String[] args) { 17 String filePath = "D://BranchWriter.txt"; 18 19 File file = new File(filePath); 20 21 try { 22 if (!file.exists()) { 23 file.createNewFile(); 24 } 25 FileWriter fw = new FileWriter(file); // 創建文件輸出流 26 27 BufferedWriter bw = new BufferedWriter(fw); // 使用緩沖區數據流封裝輸出流 28 for (int i = 0; i < 100; i++) { //循環寫入100行數據 29 30 bw.write("Java交互管道——IO流".toCharArray());// 寫入數據到輸出流 31 32 bw.newLine(); // 寫入換行符 33 34 bw.flush(); // 刷新緩沖區 35 } 36 37 System.out.println("成功寫入數據!"); 38 39 } catch (IOException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 } 44 }
3、刪除指定文件
File類的delete()方法可以實現刪除指定的文件,首先使用目標文件路徑創建File類的實例對象,然后再調用File類的delete()方法。
package com.zch.io; import java.io.File; public class FileDelete { public static void main(String[] args) { String filePath = "D://word.txt"; File file = new File(filePath); delFile(file); } public static void delFile(File file) { if (!file.exists()) { System.out.println("文件不存在!"); return; } boolean rs = file.delete(); if (rs) { System.out.println("文件刪除成功!"); } else { System.out.println("文件刪除失敗!"); } } }
————————————————
版權聲明:本文為CSDN博主「Christopher Cheung」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zch19960629/java/article/details/77917739