Java 基礎 (IO流原理及流的分類)


Java IO 原理

  1. I/O是Input/Output的縮寫,I/O技術是非常實用的技術,用於如讀/寫文件,網絡通訊等。 處理設備之間的數據傳輸。
  2. Java程序中,對於數據的輸入/輸出操作以“流(stream)”的方式進行。
  3. java.io包下提供了各種“流”類和接口,用以獲取不同種類的數據,並通過標准的方法輸入或輸出數據。

● 輸入input:讀取外部數據(磁盤、光盤等存儲設備的數據)到程序(內存)中。

● 輸出output:將程序(內存)數據輸出到磁盤、光盤等存儲設備中。

流的分類

  1. 按操作數據單位不同分為:字節流(8 bit),字符流(16 bit)
  2. 按數據流的流向不同分為:輸入流,輸出流
  3. 按流的角色的不同分為:節點流,處理流

字符流例子

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
    }


}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM