java IO流進行檔案的複製和加密解密
本節主要介紹下面內容
檔案的複製
目錄
用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 |