Java 基礎(IO流原理及流的分類)
阿新 • • 發佈:2021-10-23
Java IO 原理
- I/O是Input/Output的縮寫,I/O技術是非常實用的技術,用於如讀/寫檔案,網路通訊等。 處理裝置之間的資料傳輸。
- Java程式中,對於資料的輸入/輸出操作以“流(stream)”的方式進行。
- java.io包下提供了各種“流”類和介面,用以獲取不同種類的資料,並通過標準的方法輸入或輸出資料。
● 輸入input:讀取外部資料(磁碟、光碟等儲存裝置的資料)到程式(記憶體)中。
● 輸出output:將程式(記憶體)資料輸出到磁碟、光碟等儲存裝置中。
流的分類
- 按操作資料單位不同分為:位元組流(8 bit),字元流(16 bit)
- 按資料流的流向不同分為:輸入流,輸出流
- 按流的角色的不同分為:節點流,處理流
字元流例子
FileReaderWriterTest.java
package com.klvchen.java; /* # 流的體系結構 抽象基類 節點流(或檔案流) 緩衝流(處理流的一種) InputStream FileiInputstream BufferedInputStream Outputstream FiLeoutputstream BufferedoutputStream Reader FileReader Bufferedreader writer Filewriter Bufferedwriter */ import org.junit.Test; import java.io.*; public class FileReaderWriterTest { public static void main(String[] args) { File file = new File("hello.txt"); //相較於當前工程 System.out.println(file.getAbsolutePath()); File file1 = new File("day09\\hello.txt"); //相較於當前工程 System.out.println(file1.getAbsolutePath()); } /* 將day09下的hello.txt檔案內容讀入程式中,並輸出到控制檯 說明點: 1. read()的理解:返回讀入的一個字元。如果達到檔案末尾,返回-1 2.異常的處理:為了保證流資源一定可以執行關閉操作。需要使用try-catch-finally處理 3.讀入的檔案一定要存在,否則就會報FiLeNotFoundException。| */ @Test public void testFileReader() { FileReader fr = null; try { //1. 例項化 File 類的物件,指明要操作的檔案 File file = new File("hello.txt"); //相較於當前 Module //2. 提供具體的流 fr = new FileReader(file); //3.資料的讀入 //read():返回讀入的一個字元。如果達到檔案末尾,返回-1 //方式一: //int data = fr.read(); //while (data != -1) { // System.out.println((char) data); // data = fr.read(); //} //方式二: int data; while ((data = fr.read()) != -1) { System.out.println((char) data); } } catch (IOException e) { e.printStackTrace(); }finally { //4.流的關閉 //try { // if ( fr != null) // fr.close(); //} catch (IOException e) { // e.printStackTrace(); //} //或 if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } //對read()操作升級:使用read的過載方法 @Test public void testFileReader1(){ FileReader fr = null; try { //1.File類的例項化 File file = new File("hello.txt"); //2.FileReader流的例項化 fr = new FileReader(file); //3.讀入的操作 //read(char[] cbuf):返回每次讀入cbuf陣列中的字元的個數。 char[] cbuf = new char[5]; int len; while ((len = fr.read(cbuf)) != -1) { //方式一: //錯誤的寫法 //for (int i = 0; i < cbuf.length; i++) { // System.out.print(cbuf[i]); //} //正確的寫法 //for (int i = 0; i < len; i++) { // System.out.print(cbuf[i]); //} //方式二: //錯誤的寫法,對應著方式一的錯誤的寫法 //String str = new String(cbuf); //System.out.print(str); //正確的寫法 String str = new String(cbuf, 0, len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { //4.資源的關閉 if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 從記憶體中寫出資料到硬碟的檔案裡。 說明: 1.輸出操作,對應的 File可以不存在的。並不會報異常 2. File對應的硬碟中的檔案如果不存在,在輸出的過程中,會自動建立此檔案。 File對應的硬碟中的檔案如果存在: 如果流使用的構造器是: FileWriter(file,false)/FileWriter(file):對原有檔案的覆蓋 如果流使用的構造器是: FileWriter(file,true):不會對原有檔案覆蓋,而是在原有檔案基礎上追加內容。 */ @Test public void testFileWrite() { FileWriter fw = null; try { //1.提供File類的物件,指明寫出到的檔案 File file = new File("hello1.txt"); //2.提供FileWriter的物件,用於資料的寫出 fw = new FileWriter(file); //3.寫出操作 fw.write("I have a dream!\n"); fw.write("you need to have a dream!"); } catch (IOException e) { e.printStackTrace(); } finally { //4.流資源的關閉 try { if (fw != null) fw.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void testFileReaderFileWrite() { FileWriter fw = null; FileReader fr = null; try { //1.建立File類的物件,指明讀入和寫出的檔案 File srcFile = new File("hello.txt"); File destFile = new File("hello2.txt"); //不能使用字元流來處理圖片等位元組資料 //File srcFile = new File("1.png"); //File destFile = new File("2.png"); //2.建立輸入和輸出的對像 fr = new FileReader(srcFile); fw = new FileWriter(destFile); //3.資料的讀入和寫入操作 char[] cbuf = new char[5]; int len; //記錄每次讀入到 cbuf 陣列中的字元的個數 while ((len = fr.read(cbuf)) != -1) { //每次寫出len個字元 fw.write(cbuf, 0 , len); } } catch (IOException e) { e.printStackTrace(); } finally { //4.關閉流資源 try { if (fw != null) fw.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fr != null) fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
位元組流例子
FileInputOutputStreamTest.java
package com.klvchen.java; import org.junit.Test; import java.io.*; /* 對於文字檔案(.txt, .java, .c, .cpp),使用字元流處理 對於非文字檔案(.jpg, .mp3 , .mp4, .avi, .doc, .ppt,...),使用位元組流處理 */ public class FileInputOutputStreamTest { //使用位元組流 FileInputStream 處理文字檔案,可能出現亂碼。 @Test public void testFileInputStream() { FileInputStream fis = null; try { //1.造檔案 File file = new File("hello.txt"); //2.造流 fis = new FileInputStream(file); //3.讀資料 byte[] buffer = new byte[5]; int len; //記錄每次讀取的位元組的個數 while ((len = fis.read(buffer)) != -1) { String str = new String(buffer, 0, len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { //4.關閉流 try { if (fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } /* 實現對圖片的複製操作 */ @Test public void testFileInputOutputStream() { FileInputStream fis = null; FileOutputStream fos = null; try { // File srcFile = new File("1.png"); File destFile = new File("3.png"); // fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); // byte[] buffer = new byte[5]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } //指定路徑下檔案的複製 public void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutputStream fos = null; try { // File srcFile = new File(srcPath); File destFile = new File(destPath); // fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); // byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void testCopyFile() { long start = System.currentTimeMillis(); //String srcPath = "H:\\download\\1.mp4"; //String destPaht = "H:\\download\\2.mp4"; String srcPath = "hello.txt"; String destPaht = "hello3.txt"; copyFile(srcPath, destPaht); long end = System.currentTimeMillis(); System.out.println("複製操作花費的時間為: " + (end - start)); //7006 } }