1. 程式人生 > >java-IO操作效能對比

java-IO操作效能對比

在軟體系統中,IO速度比記憶體速度慢,IO讀寫在很多情況下會是系統的瓶頸。

在java標準IO操作中,InputStream和OutputStream提供基於流的IO操作,以位元組為處理單位;Reader和Writer實現了Buffered快取,以字元為處理單位。

從Java1.4開始,增加NIO(New IO),增加快取Buffer和通道Channel,以塊為處理單位,是雙向通道(可讀可寫,類似RandomAccessFile),支援鎖和記憶體對映檔案訪問介面,大大提升了IO速度。

以下例子簡單測試常見IO操作的效能速度。

/**
 * 測試不同io操作速度
 * 
 * @author peter_wang
 * @create-time 2014-6-4 下午12:52:48
 */
public class SpeedTest {
    private static final String INPUT_FILE_PATH = "io_speed.txt";
    private static final String OUTPUT_FILE_PATH = "io_speed_copy.txt";

    /**
     * @param args
     */
    public static void main(String[] args) {
        long ioStreamTime1 = ioStreamCopy();
        System.out.println("io stream copy:" + ioStreamTime1);

        long ioStreamTime2 = bufferedStreamCopy();
        System.out.println("buffered stream copy:" + ioStreamTime2);

        long ioStreamTime3 = nioStreamCopy();
        System.out.println("nio stream copy:" + ioStreamTime3);
        
        long ioStreamTime4 = nioMemoryStreamCopy();
        System.out.println("nio memory stream copy:" + ioStreamTime4);
    }

    /**
     * 普通檔案流讀寫
     * 
     * @return 操作的時間
     */
    private static long ioStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new FileOutputStream(OUTPUT_FILE_PATH);
            int read = is.read();
            while (read != -1) {
                os.write(read);
                read = is.read();
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * 加入快取的檔案流讀寫, Reader預設實現快取,只能讀取字元檔案,無法準確讀取位元組檔案如圖片視訊等
     * 
     * @return 操作的時間
     */
    private static long bufferedStreamCopy() {
        long costTime = -1;
        FileReader reader = null;
        FileWriter writer = null;
        try {
            long startTime = System.currentTimeMillis();
            reader = new FileReader(INPUT_FILE_PATH);
            writer = new FileWriter(OUTPUT_FILE_PATH);
            int read = -1;
            while ((read = reader.read()) != -1) {
                writer.write(read);
            }
            writer.flush();
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * nio操作資料流
     * 
     * @return 操作的時間
     */
    private static long nioStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        FileOutputStream os = null;
        FileChannel fi = null;
        FileChannel fo = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new FileOutputStream(OUTPUT_FILE_PATH);
            fi = is.getChannel();
            fo = os.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (true) {
                buffer.clear();
                int read = fi.read(buffer);
                if (read == -1) {
                    break;
                }
                buffer.flip();
                fo.write(buffer);
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fi != null) {
                    fi.close();
                }
                if (fo != null) {
                    fo.close();
                }
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * nio記憶體對映操作資料流
     * 
     * @return 操作的時間
     */
    private static long nioMemoryStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        //對映檔案輸出必須用RandomAccessFile
        RandomAccessFile os = null;
        FileChannel fi = null;
        FileChannel fo = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new RandomAccessFile(OUTPUT_FILE_PATH, "rw");
            fi = is.getChannel();
            fo = os.getChannel();
            IntBuffer iIb=fi.map(FileChannel.MapMode.READ_ONLY, 0, fi.size()).asIntBuffer();
            IntBuffer oIb = fo.map(FileChannel.MapMode.READ_WRITE, 0, fo.size()).asIntBuffer();
            while(iIb.hasRemaining()){
                int read = iIb.get();
                oIb.put(read);
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fi != null) {
                    fi.close();
                }
                if (fo != null) {
                    fo.close();
                }
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

}
執行結果:
io stream copy:384
buffered stream copy:125
nio stream copy:12
nio memory stream copy:10

結論分析:

最普通的InputStream操作耗時較長,增加了快取後速度增加了,用了nio和記憶體對映訪問檔案,速度最快。

相關推薦

java-IO操作效能對比

在軟體系統中,IO速度比記憶體速度慢,IO讀寫在很多情況下會是系統的瓶頸。 在java標準IO操作中,InputStream和OutputStream提供基於流的IO操作,以位元組為處理單位;Reader和Writer實現了Buffered快取,以字元為處理單位。 從Jav

20170831 - A - Java IO操作

throw 發生 輸入 連接 char gbk erro 二進制 utf 1 當需要將對象轉化為字節用什麽?對象流Person p = new Person("蒼老師",18,"男" ,list);System.out.println(p); FileOutputStre

java IO操作:FileInputStream,FileOutputStream,FileReader,FileWriter實例

tput stream com -h port pri exc public 父類 FileInputStream <span style="font-family:Verdana;">import java.io.File; impo

Java IO操作常犯的錯

讀寫資料時的坑 如果檔案比較大時,一次性讀取可能會出現記憶體溢位的情況 byte[] bytes = new bytes[is.available()]; is.read(bytes); 迴圈讀取,寫出時可能會出現有重複位元組 byte[] bytes = ne

Java IO操作—位元組流(OutputStream、InputStream)和字元流(Writer、Reader)

流的概念 在程式中所有的資料都是以流的方式進行傳輸或儲存的,程式中需要資料的時候就用輸入流讀取資料,而當程式需要將一些資料儲存起來的時候,就要使用輸出流完成。 程式中的輸入輸出都是以流的形式儲存的,流中儲存的實際上全部是位元組檔案。 位元組流和字元流 在java.io包中操作檔

JAVAIO操作

一、JAVA I/O 輸入輸出流   1:編碼問題   2:File類的使用   3:RandomAccessFile的使用   4:位元組流的使用   5:字元流的使用   6:物件的序列化和反序列化     2: file類的使用。   java.io.file類用

DocumentFragment物件詳解,與傳統DOM操作效能對比

一、前言 最近專案不是很忙,所以去看了下之前總想整理的重匯和迴流的相關資料,關於迴流優化,提到了DocumentFragment的使用,這個物件在3年前我記得是有看過的,但是一直沒深入瞭解過,所以這裡做個整理。後面會把重匯,迴流也做個整理,不鴿。 二、DocumentFragment物件是什麼? MDN

C++拾趣——STL容器的插入、刪除、遍歷和查詢操作效能對比(ubuntu g++)——遍歷和查詢

遍歷 從前往後 元素個數>15000 traversal_begin_16384_highest         表現最差的是unordered_multiset。其在遍歷到1000個左右的元素時發生較高的延時操作,然後又穩定下來。         除了

Java IO 操作

IO操作 Java對資料的操作都是通過流的方式,IO流用來處理裝置之間的資料傳輸,檔案上傳和檔案下載,Java用於操作流的物件都在IO包,NIO(New IO)包中。 建立檔案 Java建立檔案的方式有三種方式,我們接下來一個一個來介紹。 File.crea

Java IO操作--壓縮包zip實現工具類

壓縮檔案大致可以分為三種:ZIP、JAR、GZ。 壓縮流 在日常的使用中經常會使用到像WinRAR或WinZIP這樣的壓縮檔案,通過這些軟體可以把一個很大的檔案進行壓縮以方便傳輸。 在JAVA中 為了減少傳輸時的資料量也提供了專門的壓縮流,可以將檔案或資料夾壓縮成ZI

Java io操作,poi匯出excel,集合自帶排序,日誌報告

java io操作,poi匯出到excel表格,sl4j日誌列印,集合自帶排序Comparator要求: 取出txt檔案中其中第50000行到60000行的資料,進行資料的解析,然後對資料的某一項進行排序,從小到大輸出到excel表格中.每一步的錯誤進行日誌列印,不要直接e

Java-IO操作

style leo 之間 dmi adl puts 保存數據 關聯 接收 IO流包括字節流(Byte)和字符流(String/char) 字節流: 在JDK中定義了兩個抽象類InputStream和OutputStream,它們是字節流的頂級父親。 InputStream的

Java各種反射效能對比

對各種方法實現get方法的效能進行了一個測試。 總共有5個測試,,每個測試都是執行1億次 1. 直接通過Java的get方法 2.通過高效能的ReflectAsm庫進行測試 3.通過Java Class類自帶的反射獲得Method測試 4.使用Java自帶的Property類獲取Method測試

Java IO操作——位元組-字元轉換流(OutputStreamWriter、InputStreamReader)

學習目標  掌握OutputStreamWriter和InputStreamReader類的作用 具體學習內容: OutputStreamWriter和InputStreamReader 在整個IO包

java-IO操作——使用帶有緩衝的字元流讀寫資料

使用BufferedReader和PrintWriter實現檔案拷貝 package Test; import java.io.BufferedReader; import java.io.Bu

Java IO操作——簡單瞭解RandomAccessFile隨機讀寫檔案操作類的使用

學習目標 掌握RandomAccessFile類的作用 可以使用RandomAccessFile讀取指定位置的資料 RandomAccessFile類的主要功能是完成隨機讀取功能,可以讀取指定位置的

Java IO操作詳解

在Java程式設計中,IO(輸入輸出)是重要的組成部分,Java應用常常需要從外界輸入資料或者把資料輸出到外界。 Java IO的核心用一句話概括:抽象類或介面之中的抽象方法會根據例項化子類的不同,會完成不同的功能。所有的IO操作都在java.io包之中進行定

JAVA IO操作

java.io.File類用於表示檔案(目錄) File類只用於表示檔案(目錄)的資訊(名稱、大小等),不能用於檔案內容的訪問 RandomAccessFile java提供的對檔案內容的訪問,既可以讀檔案,也可以寫檔案。 RandomAccessFile

Java IO操作——檔案操作類File的使用

 學習目標 掌握File類的使用 可以使用File類中的方法對檔案進行操作。 在整個Java的學習中,個人感覺學習較為困難的地方就是IO,因為整個IO是非常龐大的,而且有很多操作的類。每個類都有各自

Java IO操作——BufferedReader(緩衝區讀取內容,避免中文亂碼)

 要點: 掌握BufferedReader類的使用 掌握鍵盤輸入的基本形式 Buffer:表示緩衝區的。之前的StringBuffer,緩衝區中的內容可以更改,可以提高效率。 如果想接收任意長度的資