1. 程式人生 > >java IO流進行檔案的複製和加密解密

java IO流進行檔案的複製和加密解密

本節主要介紹下面內容

檔案的複製

目錄

用FileInputStream複製

用BufferedInputStream複製

檔案的加密:


用FileInputStream複製

檔案的拷貝需要將檔案讀入到記憶體中,再將檔案從記憶體中寫入到硬碟中,

需要用檔案輸入流FileInputStream讀取檔案,

每次讀取一個byte陣列的內容,

用檔案輸出流FileOutputStream將byte陣列寫出到檔案

畫個圖

示例:用FileInputStream和FileOutputStream拷貝檔案

import java.io.*;

public class FileCopy {
    public static void main(String[] args){
        try(    FileInputStream fis=new FileInputStream("G:\\x269all.rmvb") ;
                FileOutputStream fos=new FileOutputStream("G:\\x270.rmvb");
                ) {
            byte [] bytes=new byte[1024];
            int temp;
            while((temp=fis.read(bytes))!=-1){
                fos.write(bytes,0,temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

用BufferedInputStream複製

用BufferedInputStream和BufferedOutputStream拷貝檔案

看下緩衝輸入流BufferedInputStream的部分原始碼:

BufferedInputStream工作工程,在自身建立一個byte陣列,呼叫read方法時,先將內容讀取到byte陣列,再從byte陣列中讀取,當byte陣列的元素被讀取完的時候,會呼叫fill方法填充本身的byte陣列,關閉BufferedInputStream時自動關閉作為引數的InputStream物件

public  class BufferedInputStream extends FilterInputStream {
     private static int DEFAULT_BUFFER_SIZE = 8192;
    //構造方法,呼叫帶兩個引數的構造方法,預設緩衝大小為8192位元組,8M
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
//帶兩個引數的構造方法,內部利用了一個長為8192的byte陣列
    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

...
}

BufferOutputStream部分原始碼

工作原理:將內容寫到BufferedOutputStream中的byte陣列,再從byte陣列中訪問,關閉BufferedOutputStream時,自動關閉作為引數的OutputStream物件

public class BufferedOutputStream extends FilterOutputStream {
   
    protected byte buf[];

   
    protected int count;

    
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }
    //建構函式,建立8192位元組大小的byte陣列,作為快取區
   
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

//重新整理快取,將快取內容通過OutputStream寫入到硬碟或者其他地方,out是父類中屬性,型別是OutputStream
    private void flushBuffer() throws IOException {
        if (count > 0) {
//out值得是OutputStream
            out.write(buf, 0, count);
            count = 0;
        }
    }

    
    @Override
    public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }

   
    //寫陣列,還是通過OutputStream的寫方法完成
    @Override
    public synchronized void write(byte b[], int off, int len) throws IOException {
        if (len >= buf.length) {
            /* If the request length exceeds the size of the output buffer,
               flush the output buffer and then write the data directly.
               In this way buffered streams will cascade harmlessly. */
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        if (len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    
    @Override
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }
}


複製過程:

可以看到,BufferedInputStream的構造方法要傳入InputStream流物件,然後建立一個長8192的byte陣列(8k),每次緩衝這麼長的陣列

說明BufferedInputStream和BufferedOutputStream也可以用來拷貝檔案,過程是先從FileInputStream中每次讀取8k讀到輸入快取區,再從輸入快取去寫到輸出快取區,再從輸出快取區通過FileOutputStream每次寫8k寫入到硬碟,減少了硬碟的讀寫次數,避免了硬碟的頻繁訪問,效率會高

畫個圖:

程式碼示例:

package io01;

import java.io.*;

public class FileCopy02 {
    public static void main(String[] args){
        try(
                BufferedInputStream bis=new BufferedInputStream(new FileInputStream("G:\\x269all.rmvb"));
                BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("G:\\x256.rmvb"));
                ) {
            int temp;
            while ((temp=bis.read())!=-1) {
//從硬碟寫入到輸入快取區,再從輸入快取區快速寫入到輸出快取區,再寫入到硬碟
                bos.write(temp);

            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

既然FileInputStream和FileOutputStream可以完成複製,為什麼還要用BufferedInputStream和BufferedOutputStream?

因為先將多個位元組寫入到記憶體中的快取區,可以減少對硬碟io的訪問,提高效率,寫入到硬碟的時候同理

檔案的加密:

前面我部落格簡單說過兩個整數a和b,a異或b兩次得到的還是a,以此可以做兩個整數交換,也可以做簡單的加密解密

示例:

package io01;

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

public class FileCode {
    public static void main(String[] args){
        try (
                FileInputStream fis=new FileInputStream("G:\\辯證法.jpg");
                FileOutputStream fos=new FileOutputStream("G:\\39.jpg");
                ){
            int temp;
            while((temp=fis.read())!=-1){
                fos.write(temp^89);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }



}
package io01;

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

public class FileDecode {
    public static void main(String[] args){
        try (
                FileInputStream fis=new FileInputStream("G:\\39.jpg");
                FileOutputStream fos=new FileOutputStream("G:\\40.jpg");
                ){
            int temp;
            while((temp=fis.read())!=-1){
                fos.write((temp)^89);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

 

參考:http://www.monkey1024.com/javase/608

G

M

T

 

 

  Chinese (Simplified)English

 

Chinese (Simplified)English

 

 

 

 

 

 

 

 

 

Text-to-speech function is limited to 200 characters

 

 

 

Options : History : Feedback : Donate Close