Java學習之路(十二):IO流

IO流的概述及其分類

  • IO流用來處理設備之間的數據傳輸,Java對數據的操做是經過流的方式
  • Java用於操做流的類都在IO包中

流按流向分爲兩種:輸入流(讀寫數據)     輸出流(寫數據)

流按操做類型分爲兩種:java

  • 字節流:字節流能夠操做任何數據,由於在計算機中任何數據都是以字節的形式存儲的
  • 字符流:字符流只能操做純字符數據,比較方便

經常使用的IO流的類

字節流的抽象父類:InputStream     OutputStream數組

字符流的抽象方法:Reader   Writeride

InputStream實現類FileInputStream

InputStream是抽象類,表示字節輸入流加密

FileInputStream從文件系統中的某個文件中得到輸入字節。FileInputStream用於讀取圖像數據之類的原始字節流。要讀取字符流,就要用FileReaderspa

構造方法:code

  • FileInputStream(File file)
  • FileInputStream(String name)

FileInputStream的構造方法能夠傳一個File對象,也能夠傳一個字符串路徑對象

成員方法:blog

  • int read()   今後輸入流中讀取到一個數據字節

案例:讀取一個txt文件數據繼承

package null08031628;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        File file = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        FileInputStream fis = new FileInputStream(file);
        int i = 0;
        while((i = fis.read()) != -1){
            System.out.println(i);
        }
     fis.close();
} }

 

OutputStream實現類FileOutputStream文件輸出流

文件輸出流就是用於將數據寫入File的輸出流接口

案例:從一個文件讀入數據寫入另外一個文件package null08031638;import java.io.File;

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Demo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub  File filein = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt"); InputStream fis = new FileInputStream(filein); //建立一個輸入流  File fileout = new File("C:/Users/Administrator/Desktop/baiduyunpan-2.txt"); OutputStream fos = new FileOutputStream(fileout); //建立一個輸出流 int i = 0; while((i=fis.read())!=-1){ fos.write(i); }
     fos.close();
     fis.close();
} }

 

經過available()方法,進行字節數組拷貝(錯誤的,不推薦的,若是文件超級大怎麼辦?)

package null08031700;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        
        FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");
        
        byte[] bs = new byte[input.available()];//定義一個文件輸入流那麼大的字節數組
        input.read(bs); //一次性將數據寫入到字節數組中
        
        out.write(bs); //一次性將文件寫入
        input.close();
        out.close();
        
        
        
    }

}

 

自定義一個大小的數組,進行一個流的讀寫(正確的方法)

package null08031707;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        
        FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");
        
        byte[] bs = new byte[8*1024];
        
        int i = 0;
        while((i=input.read(bs))!=-1){
            out.write(i);
        }
        out.close();
        input.close();
        
    }

}

 

經過字節數組的方法操做流,其實就是至關因而建立了一個緩衝區

自帶緩衝區的實現類BufferedInputStream和BufferedOutputStream

BufferedInputStream

  • 內置了一個緩衝區(就是以前定義的那個數組)
  • 從BufferedInputStream中讀取一個字節時,BufferedInputStream會一次性的讀入8192個,放在緩衝區,在返回給程序
  • 程序再次讀取時,就不會再從文件中取了,直接從緩衝區獲取
  • 知道緩衝區中的全部都被用過了,BufferedInputStream才從新從文件中讀取8192個

BufferedOutputStream

  • 內置了一個緩衝區(數組)
  • 程序向流中寫入字節時,不會直接寫到文件,而是先寫入緩衝區當中
  • 知道緩衝區寫滿,BufferedOutputStream纔會把緩衝區中的數據一次性寫入文件

一個小小的例子:

package null08031732;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        FileInputStream fis = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        
        FileOutputStream fos = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-4.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        int i;
        while((i=bis.read())!=-1){
            bos.write(i);
        }
        bis.close();
        bos.close();
    }

}

 

帶Buffered的流和本身寫的字節數組緩衝對比

  • 字節寫的數組在速度上回略勝一籌,由於本身寫的讀和寫的操做都是在同一個數組之中
  • 而Buffered操做的是兩個數組,因此效率低於一個的

BufferedOutputStream中的一些方法

  • flush()方法:用來刷新緩衝區,刷新後就能夠再次寫入了
  • close()方法:關閉流,並且在關閉先後會刷新一次緩衝區

補充 

字節流讀寫中文時亂碼的問題

字節流讀取中文:

  • 字節流讀取中文的問題
  • 字節流在讀取中文的時候有可能會讀到半個中文,形成亂碼

字節流寫入中文的問題:

  • 字節流直接操做的字節,因此寫入中文的時候必須將字符串轉換成字節數組
  • 寫出回車換行write("\r\n".getBytes())

流的標準處理異常代碼1.6版本前

package null08041019;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        FileInputStream fis = null;
        FileOutputStream fos = null;
        
        try{
            fis = new FileInputStream("");
            fos = new FileOutputStream("");
            
            int b;
            while((b=fis.read())!=-1){
                fos.write(b);
            }
        }finally{
            try{
                fis.close();
            }finally{
                fos.close();
            }
        }
    }
}

 

流的處理1.7版本

package null08041024;

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

public class Demo01 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        try(
            //寫在括號中的代碼,執行完成後,會自動調用對象的close方法
            //能寫在括號中的代碼的類必定是要繼承AutoCloseable接口的類
            FileInputStream fis = new FileInputStream("");
            FileOutputStream fos = new FileOutputStream("");
                
        ){
            int i;
            while((i=fis.read())!=-1){
                fos.write(i);
            }
        }
    }

}

一個圖片加密的例子:

package null08041031;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Demo01 {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in); 
        System.out.println("請將圖片放到和此文件的同級目錄下");
        System.out.println("請輸入要加密的文件名:");
        String fileName = sc.nextLine();
        System.out.println("請輸入加密後的文件名:");
        String endFileName = sc.nextLine();
        System.out.println("請輸入密碼:");
        String pwd = sc.nextLine();
        int pwdInt = Integer.parseInt(pwd);
        
        try(
            FileInputStream fis = new FileInputStream(fileName);
            FileOutputStream fos = new FileOutputStream(endFileName);
            ){
            int i;
            while((i=fis.read())!=-1){
                fos.write(i^pwdInt);
            }
        }finally{
            System.out.println("加密結束");
        }

    }

}
代碼
相關文章
相關標籤/搜索