#Java中I/O使用入門詳解(1)

Java中I/O使用入門詳解(1)

本文介紹了 FileInputStream,FileOutputStream等常用輸入輸出流的使用方式,(來自於以前的學習筆記,現整理出來和大家分享).
通俗易懂,老少皆宜O(∩_∩)O~

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * IO的分類:
 *      流向:
 *          輸入流:讀取數據
 *          輸出流:寫入數據
 *      數據類型:
 *          字節流
 *              字節輸入流   讀取數據    InoutStream
 *              字節輸出流   寫入數據    OutputStream
 *          字符流
 *              字符輸入流   讀取數據    Reader
 *              字符輸出流   寫入數據    Writer
 * 
 *      注意:一般在探討IO流,不說的話是按數據類型來說的
 * 
 * 需求:往一個文本文件中寫入一句話:"hello,IO".
 * 
 * 分析:
 *      A:這個最好用字符流實現,這裏用字節流
 *      B:由於我是想往文件中寫一句話,所以我們用字節輸出流
 * 通過上面的分析後我們知道要使用OutputStream
 * 但是通過查看API,我們發現該流對象是一個抽象類,不能實例化
 * 所以我們要找一個具體的子類,這個時候很簡單,實際上,我們是要往文件中寫東西
 * 文件單詞:File
 * 然後用的是字節流,連起來就是FileOutputStream
 * 注意:每種基類的子類都是以父類名作爲後綴名
 * 
 * 查看FileOutputStream構造方法
 *      FileOutputStream(File file)
 *      FileOutputStream(String name)
 */
public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //創建字節流輸出對象
        //FileOutputStream(File file)
//      File file= new File("fos.txt");
//      FileOutputStream fos=new FileOutputStream(file);
        FileOutputStream fos=new FileOutputStream("fos.txt");
        /*
         * 創建字節輸出流對象做了幾件事情
         * 1:調用系統功能去創建文件
         * 2:創建fos對象
         * 3:把fos對象指向這個文件
         */

        //寫數據
        fos.write("hello,IO".getBytes());

        //釋放資源
        fos.close();
        /*
         * 爲什麼一定要close呢?
         * A:關閉流對象,使流對象變成垃圾,以免後面別人接着寫
         * B:通知系統去釋放相關的資源
         */
    }
}

1.FileOutputStream

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 字節輸出流操作步驟
 * A:創建字節輸出流對象
 * B:調用write()方法
 * C:釋放資源
 * 
 * public void write(int b);寫一個字節
 * public void write(byte[] b);寫一個字節數組
 *  public void write(byte[] b,int Off,int len);寫一個字節數組的一部分
 */
public class FileOutputStreaDemo2 {
    public static void main(String[] args) throws IOException {
        //創建字節流輸出流對象
        //OutputStream os=new FileOutputStream("fos2.txt);//這是多態
        FileOutputStream fos=new FileOutputStream("fox2.txt");

        //調用write()方法
        fos.write(97);//97----底層是二進制數組----通過記事本打開-----找97對應的字符值----a

        //public void write (byte[] b):寫一個字節流數組
        byte[] bys={97,98,99,100,101};
        fos.write(bys);

        //public void write(byte[] b,int Off,int len);寫一個字節數組的一部分
        fos.write(bys,1,3);
        fos.close();
    }
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 如何實現數據的換行?
 *      爲什麼沒有換行呢?因爲只寫了字節數據,並沒有寫入換行符號
 *      如何實現換行?寫入換行符號即可
 *      剛纔用"\n"我們看到有些文本文件打開是可以的,但用Windows自帶卻不行
 *          原因:不同的系統對於換行符號識別是不一樣的
 *          windows:\r\n
 *          linux:\n
 *          Mac:\r
 * 
 *      而一些高級寫字本軟件可識別任意的換行符的
 * 如何實現數據的追加寫入?
 *      用構造方法待第二個參數爲true的情況即可
 */
public class FileOutputStreamDemo3 {
    public static void main(String[] args) throws IOException {
        //創建字符輸出流
        //FileOutputStream fos=new FileOutputStream("fos3.txt");

        FileOutputStream fos=new FileOutputStream("fos3.txt",true);

        //寫數據
        for(int i=0;i<10;i++){
            fos.write(("hello"+i).getBytes());
            fos.write("\n".getBytes());
        }
        fos.close();

    }
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 加入異常處理的字節輸出流操作
 * 
 */
public class FileOutputStreamDemo4 {
    public static void main(String[] args) {
FileOutputStream fos=null;
        try {
            fos = new FileOutputStream("fos4.txt");
            fos.write("java".getBytes());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally{
            //如果fos不是null,才需要close()
            if(fos!=null){
                try {
                    fos.close();
                    } catch (IOException e) {   
                        e.printStackTrace();
                    }
                }
            }
    }
}

2.FileInputStream

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 *字節輸入流操作步驟
 *A:創建字節輸入流對象
 *B:調用read()方法讀取數據,並把它顯示到控制檯
 *C:釋放數據
 * 
 * 讀取數據的方式
 * A:int read();一次讀取一個字節
 * B:int read(byte[] b);一次讀取一個字節數組
 * 
 */
public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //FileInputStream(String name);
        FileInputStream fis=new FileInputStream("fis.txt");

        //用int read();
        //第一次讀取
//      int by=fis.read();
//      System.out.println(by);
//      System.out.println((char)by);
//      
//      //第二次讀取
//              by=fis.read();
//              System.out.println(by);
//              System.out.println((char)by);
//      //第三次讀取
//              by=fis.read();
//              System.out.println(by);
//              System.out.println((char)by);
        //我們發現代碼的重複度很高,應該用循環改進      
        //而用循環,最麻煩的是如何控制循環的條件       
        //多測兩次後發現,讀取的結果爲-1,說明已經讀取到文件的末尾了        

        //循環改進
//      int by=fis.read();
//      while(by!=-1){
//          System.out.print((char)by);
//          by=fis.read();
//      }

        //最終版代碼
        int by=0;
        //讀取,賦值,判斷
        while((by=fis.read())!=-1){
            System.out.println((char) by);
        }           
        //釋放資源
        fis.close();
    }
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 一次讀取一個字節數組
 * 返回值是讀取字節的
 */
public class FileInputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //創建字節輸入流對象
        FileInputStream fis=new FileInputStream("fis2.txt");

        //讀取數據
        //定義一個字節數組
        //第一次讀取
//      byte[] bys=new byte[5];
//      int len=fis.read(bys);
//      System.out.println(new String(bys,0,len));
//      

//      byte[] bys =new byte[20];
//      int len=0;
//      while((len=fis.read(bys))!=-1){
//          System.out.println(new String (bys,0,len));
//          //System.out.println(new String (bys)此做法有問題,千萬要注意
//      }

        //最終版
        //數組的長度一般是1024或者1024的倍數
        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            System.out.println(new String (bys,0,len));
        }
        //釋放資源
        fis.close();
    }
}

3.一些文件複製應用的例子

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 
 * 複製文本文件
 * 
 * 數據源:從哪裏來
 * a.txt        讀取數據 FileinputStream
 * b.txt        寫數據 FileOutputStream
 * 目的地:到哪裏去
 * b.txt
 * 
 * 這一次複製中文沒有出現任何問題,爲什麼?
 * 上一次我們出現問題是由於我們把每次獲取到一個字節數據,就把該字節數據轉換爲字符數據
 * 而這一次,卻是通過IO流讀取數據,你讀取一個字節,我就寫入一個字節,沒有存在任何轉換
 * 他會自己轉換
 * 
 */
public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        //封裝數據源
        FileInputStream fis=new FileInputStream("a.txt");
        //封裝目的地
        FileOutputStream fos=new FileOutputStream("b.txt");

        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }

        //釋放資源(先關誰都行)
        fos.close();
        fis.close();
    }
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 
 * 複製文本文件
 * 
 * 數據源:從哪裏來
 *              c:\\a.txt       讀取數據 FileinputStream        
 * 目的地:到哪裏去
 *              d:\\b.txt       寫數據 FileOutputStream
 * 
*/
public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        //封裝數據源
        FileInputStream fis=new FileInputStream("c:\\a.txt");
        //封裝目的地
        FileOutputStream fos=new FileOutputStream("d:\\b.txt");

        //複製數據
        int by=0;
        while ((by=fis.read())!=-1){
            fos.write(by);
        }
        fis.close();
        fos.close();
    }
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 需求:把e:\\a.jpg內容複製到當前項目下的aa.jpg中
 * 
 */
public class CopyImageDemo {
    public static void main(String[] args) throws IOException {
        //封裝數據源
        FileInputStream fis=new FileInputStream("e:\\a.jpg");

        //封裝目的地
        FileOutputStream fos =new FileOutputStream("aa.jpg");

        //複製數據
        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }
        //釋放資源
        fos.close();
        fis.close();
    }
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 把D:\\a.txt內容複製到E:\\b.txt中
 */
public class CopyFileDemo {
     public static void main(String[] args) throws IOException {
        //封裝數據源
        FileInputStream fis=new FileInputStream("d:\\a.txt"); 

        //封裝目的的
        FileOutputStream fos=new FileOutputStream("e:\\b.txt");

        //複製數據
        byte[] bys=new byte[1024];
        int len=0;
        while((len= fis.read(bys))!=-1){
            fos.write(bys,0,len);
        }
        //釋放資源
        fis.close();
        fos.close();
    }
}

4.BufferedOurtputStream與BufferedInputStream

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 我們通過定義數據的方式的確比以前一個一個讀取有效率得多,看來有一個緩衝區是很好的
 * 其實java開始設計時,就考慮了這個問題,就專門提供了緩衝區的字節類
 * 這種類被稱爲:緩衝區類(高效類)
 * 寫數據:BufferedOutputStream
 * 讀數據:BufferedInputStream
 * 
 * 構造方法可以指定緩衝區大小,但我們一般用不上,因爲默認的緩衝區大小就夠了
 * 
 * 爲什麼不傳遞一個具體的文件或文件路徑,而是傳送一個OutputStream對象呢?
 * 原因很簡單,字節緩衝區僅僅提供緩衝區,爲高效而設計的,但是呢,真正的讀寫操作還得靠基本的流對象
 * 
 */
public class BufferedOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //BufferedOutputStream(OutputStream out);
//      FileOutputStream fos=new FileOutputStream("bos.txt");       
//      BufferedOutputStream bos=new BufferedOutputStream(fos);
        BufferedOutputStream bos=new BufferedOutputStream(
                            new FileOutputStream("bos.txt"));

        //寫數據
        bos.write("hello".getBytes());
        bos.close();
    }
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class BufferedInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //BufferedInputStream(InputDtream in)
        BufferedInputStream bis=new BufferedInputStream(
                new FileInputStream("bos.txt"));

        //讀數據
//      int by =0;
//      while((by=bis.read())!=-1){
//          System.out.println((char) by);
//      }

        byte[] bys=new byte[1024];
        int len =0;
        while ((len=bis.read(bys))!=-1){
            System.out.println(new String(bys,0,len));
        }

        bis.close();
    }
}

最後,我們來比較一下四種讀寫2方式的速度差異:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 把e:\\下的a.mp4複製到當前目錄下的aa.mp4
 * 
 * 字節流四種方式複製文件
 * 基本字節流一次讀寫一個字節
 * 基本字節流一次讀寫一個字節數組
 * 高效字節流一次讀寫一個字節
 * 高效字節流一次讀寫一個字節數組
 * 
 */
public class CopyMp4Demo {
    public static void main(String[] args) throws IOException {
        long start=System.currentTimeMillis();
        //method1("e:\\a.mp4","copy1.mp4");共耗時:  81700ms
        //method2("e:\\a.mp4","copy2.mp4");共耗時:  326ms
        //method3("e:\\a.mp4","copy3.mp4");共耗時:  1899ms
        //method4("e:\\a.mp4","copy4.mp4");共耗時:  137ms
        long end=System.currentTimeMillis();
        System.out.println("共耗時:  "+(end-start)+"ms");
    }


    //基本字節流一次讀寫一個字節
    private static void method1(String srcString, String destString) throws IOException {
        FileInputStream fis=new FileInputStream(srcString);
        FileOutputStream fos=new FileOutputStream(destString);

        int by=0;
        while((by=fis.read())!=-1){
            fos.write(by);
        }
        fos.close();
        fis.close();        
    }


    //基本字節流一次讀寫一個字節數組
        private static void method2(String srcString, String destString) throws IOException {
            FileInputStream fis=new FileInputStream(srcString);
            FileOutputStream fos=new FileOutputStream(destString);

            byte[] bys=new byte[1024];
            int len=0;
            while((len=fis.read(bys))!=-1){
                fos.write(bys,0,len);
            }


            fos.close();
            fis.close();        
        }

        //高效字節流一次讀寫一個字節
        private static void method3(String srcString, String destString) throws IOException {
            BufferedInputStream bis=new BufferedInputStream(
                    new FileInputStream(srcString));
            BufferedOutputStream bos=new BufferedOutputStream(
                    new FileOutputStream(destString));

            int by=0;
            while((by=bis.read())!=-1){
                bos.write(by);
            }
            bos.close();
            bis.close();        
        }

        //高效字節流一次讀寫一個字節數組
        private static void method4(String srcString, String destString) throws IOException {
                    BufferedInputStream bis=new BufferedInputStream(
                            new FileInputStream(srcString));
                    BufferedOutputStream bos=new BufferedOutputStream(
                            new FileOutputStream(destString));

                    byte[] bys=new byte[1024];
                    int len=0;
                    while((len=bis.read(bys))!=-1){
                        bos.write(bys,0,len);
                    }
                    bos.close();
                    bis.close();        
                }
}

5.關於I/O使用的小結提綱

(1)用於在設備間數據傳輸的操作

(2)分類:

A:流向

        輸入流 --> 讀取數據
        輸出流 --> 寫入數據

B:數據類型

        字節流
                字節輸入流
                字節輸出流
        字符流
                字符輸入流
                字符輸出流
    a:如果我們沒明確說明按照什麼分,默認按照數據類型分
    b:除非文件用Windows自帶記事本打開我們能夠讀懂,才採用字符流,否則採用字節流

(3)FilOutoutStream寫出數據

A:操作步驟

        a:創建自己人輸出流操作對象
        b:調用Write()方法
        c:釋放資源

B:代碼體現:

        FileOutputSream fos=new FileOutputStream("fos.txt");

        fos.write("hello".getBytes());

        fos.close();

C:要注意問題?

        a:創建字節輸出流對象做了幾件事情?
        b:爲啥要close()?
        c:如何實現數據的換行?
        d:如何實現數據的追加寫入?

(4)FIleInputStream讀取數據

A:操作步驟
        a:創建字節輸入流對象
        b:調用read()方法
        c:釋放資源
B:代碼實現:
        FileInputStream fis =new FileInputStream("fos.txt");

        //方式一
        int by=0;
        while((by=fis.read()!=-1)){
            System.out.print((char)by);
        }   

        fis.close;

        //方式二
        byte[] bys=new byte[1024];
        int len=0;
        while((len=fis.read(bys))!=-1){
            System.out.print(new String(bys,0,len));
        }

        fis.close;

(5)案例:

    A:複製文本文件
    B:複製圖片
    C:複製視頻

(6)字節緩衝區流

    A:BufferedOutputStream
    B:BufferedIntputStream

(7)例子:幾種實現

    A:複製文本文件
    B:複製圖片
    C:複製視頻
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章