1. 程式人生 > >Java-IO 字節流的使用和效率比較

Java-IO 字節流的使用和效率比較

操作 mp4 tran 方法 區別 讀寫文件 read 內容 ddr

打算做一個系列,前面講了基本的字符流的用法,這篇博客介紹一下字節流的基本用法:

一、基本使用:

基本字節流:

FileInputStream FileOutputStream

BufferedInputStream BufferedOutputStream

註意點,字節流和字符流的使用方式基本類似,有一點區別是使用字節流來讀寫文件是不需要使用flush函數的,原因:

1、字符流需要使用到flush函數將寫在緩沖區的字符沖到文件,因為字符流=編碼字典+字節流,事實上字符流讀取的還是字節,但是讀完一個字節之後它會根據字符集去查找相應的字符;

2、字節流直接操作的就是字節,所以它進行寫入的時候直接就寫入到文件中了,不需要再進行flush;

3、FileInputStream FileOutputStream是由繼承flush方法的,但是這個方法什麽也沒有做。在FileOutputStream中flush源碼是這樣子的:

    public void flush() throws IOException {
    }

  之所以還需要這個函數是子類可能是需要用到的。

下面是基本使演示用代碼:

兩個全局變量分別是:

1、LINE_SEPARATE:當前系統環境的換行符;

2、ROOT_DIR:當前項目的運行目錄(我們創建的文件如果沒有特殊指定就是在這個目錄下);

    private final static String LINE_SEPARATE = System.getProperty("line.separator");
    private final static String ROOT_DIR=System.getProperty("user.dir");
    public static void main(String[] args) throws IOException {

        System.out.println(ROOT_DIR);

        try (OutputStream out = new FileOutputStream("in.txt")) {
            out.write("湖畔".getBytes());
            out.write(LINE_SEPARATE.getBytes());
            out.write("123456".getBytes());
            out.write(LINE_SEPARATE.getBytes());
        }

        try (InputStream in = new FileInputStream("in.txt")) {

            byte[] contentArray = new byte[512];
            int length = in.read(contentArray);

            try (OutputStream out = new FileOutputStream("newIn.txt")) {
                out.write(contentArray, 0, length);
                System.out.println(new String(contentArray, 0, length));
            }
        }
    }

 註意;我上面寫入的內容很短,讀一次512比特的數組肯定都能夠全部讀取出來,所以就不使用while循環了。

下面是輸出結果:

E:\EXE\eke.test.first
湖畔
123456

二、使用帶有緩沖區的BufferedInputStream和BufferedOutputStream並使用不同的方法復制一個文件比較效率:

(這些方法的比較是看傳智播客視頻後寫的)

直接上代碼:

public static void main(String[] args) throws IOException {
    long copy_2_start_time = System.currentTimeMillis();
copy_2();
long copy_2_end_time = System.currentTimeMillis();
System.out.println("copy_2 運行耗時:" + (copy_2_end_time - copy_2_start_time) + " 毫秒");

long copy_1_start_time = System.currentTimeMillis();
copy_1();
long copy_1_end_time = System.currentTimeMillis();
System.out.println("copy_1 運行耗時:" + (copy_1_end_time - copy_1_start_time) + " 毫秒");

long copy_0_start_time = System.currentTimeMillis();
copy_0();
long copy_0_end_time = System.currentTimeMillis();
System.out.println("copy_0 運行耗時:" + (copy_0_end_time - copy_0_start_time) + " 毫秒");

}

private static void copy_1() throws IOException {
try (FileInputStream in = new FileInputStream("環保小視頻.mp4")) {
try (BufferedInputStream bufin = new BufferedInputStream(in, 102400)) {
int content;
try (FileOutputStream out = new FileOutputStream("copy_1.mp4")) {
try (BufferedOutputStream bufout = new BufferedOutputStream(out, 102400)) {
while ((content = in.read()) != -1) {
bufout.write(content);
}
}
}
}
}
}

private static void copy_0() throws IOException {
try (FileInputStream in = new FileInputStream("環保小視頻.mp4")) {
try (FileOutputStream out = new FileOutputStream("copy_0.mp4")) {
byte[] contentArray = new byte[102400];
int length = 0;
while ((length = in.read(contentArray)) != -1) {
out.write(contentArray, 0, length);
}
}
}
}

private static void copy_2() throws IOException {
try (FileInputStream in = new FileInputStream("環保小視頻.mp4")) {
try (FileOutputStream out = new FileOutputStream("copy_2.mp4")) {
int ch;
while ((ch = in.read()) != -1) {
out.write(ch);
}
}
}
}

  輸出結果:

Connected to the target VM, address: ‘127.0.0.1:53146‘, transport: ‘socket‘
copy_2 運行耗時:69494 毫秒
copy_1 運行耗時:9119 毫秒
copy_0 運行耗時:9 毫秒
Disconnected from the target VM, address: ‘127.0.0.1:53146‘, transport: ‘socket‘

 分析:

copy_2方法是使用FileOutputStream和FileInputStream,一個自己一個字節的讀;速度慢的想死;

copy_1方法使用了帶緩沖區的BufferedInputStream 和BufferedOutputStream,速度有了很大的提高,但是還是慢的一匹;

copy_0方法是使用了自己創建的緩沖區,每次讀取102400個字節,竟然只需要9毫秒。

其中copy_1和copy_0的區別是在讀取和寫入的時候都是從各自的緩沖區取,但是copy_1沒有使用數組,一次還是只讀取一個字節,所以速度上被copy_0給拋下了。

Java-IO 字節流的使用和效率比較