Java粗淺認識-I/O(一)

I/O

IO到底是什麼?I/O是(Input和Output)輸入輸出,在操作系統層面,Input就是從輸入設備(磁盤驅動器、網絡和終端)讀取數據到內存中,
Output就是從內存中把數據輸出到輸出設備中(磁盤驅動器、網絡和終端),而這些輸入輸出設備都是在Linux系統當中,所有的輸入、輸出設備都被抽象化爲文件,二文件就是一個n個字節的序列,文件又被分類爲普通文件(二進制和文本),目錄,套接字(用於網絡通信)。

Unix系統上支持的I/O模型

同步IO,異步IO
同步IO,阻塞式IO非阻塞式IOIO複用信號驅動IO,都是同步IO,不同之處在於,應用系統調用內核進行數據訪問時的兩個階段中的第一個階段等待數據是否阻塞,第二個階段都是阻塞式的,從內核把數據返回給應用程序
異步IO,則是在兩個階段都不會阻塞當前進程或線程

阻塞式I/O

非阻塞式I/O

I/O複用

信號驅動

異步I/O

Java中的IO發展

java1.0中就存在阻塞式IO,就是常見的基於Stream、File、RandomAccessFile、Writers和Readers的IO處理,
java1.4中引入了NIO,主要解決,第一階級等待數據是否阻塞的問題,IO複用式的IO操作,引入了新的處理的對象,如Channel、Selecotr、Buffer緩衝區
java1.7中引入了NIO2,引入了異步IO(這裏需要注意,真正在現在unix操作系統上,是不支持異步IO,只有Windows操作系統才實現了真正意義上的異步IO),
引入新的類;新的文件系統抽象,如:Path、Files工具類等

接下來,針對上面的內容,一一寫代碼舉例:

阻塞式I/O

/**
     * 基於java 流文件複製,這裏面涉及到的異常處理,資源回收,位運算等,後面會一一講解
     *
     * @param sourceFileName
     * @param targetFileName
     */
    public static void copyFile(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);
        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(sourceFile);
            outputStream = new FileOutputStream(targetFile);
            byte[] buffer = new byte[1 << 10];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void fileCopyWithBuffer(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);

        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        InputStream inputStream;
        OutputStream outputStream;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            inputStream = new FileInputStream(sourceFile);
            outputStream = new FileOutputStream(targetFile);
            bufferedInputStream = new BufferedInputStream(inputStream);
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            byte[] buffer = new byte[1 << 10];
            int len;
            while ((len = bufferedInputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //這裏資源關閉,沒有顯示關閉inputStream和outputStream,那是因爲,buffered**的關閉操作,會關閉底層的內嵌的stream
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 這裏涉及到一個亂碼問題
     *
     * @param sourceFileName
     * @param targetFileName
     */
    public static void copyFileWithCharacterStream(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);
        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        Reader reader = null;
        Writer writer = null;
        try {
            reader = new FileReader(sourceFile);
            writer = new FileWriter(targetFile);
            char[] chars = new char[1 << 10];
            int len;
            while ((len = reader.read(chars)) != -1) {
                writer.write(chars, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 這裏有字符亂碼問題
     *
     * @param sourceFileName
     * @param targetFileName
     */
    public static void copyFileWithBuffedCharacterStream(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);
        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        Reader reader;
        Writer writer;
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            reader = new FileReader(sourceFile);
            writer = new FileWriter(targetFile);
            bufferedReader = new BufferedReader(reader);
            bufferedWriter = new BufferedWriter(writer);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                bufferedWriter.write(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 文本文件編解碼過程,文本文件(有自己的字符集)->StreamDecoder做解碼(傳入進去的字符集)
     * ->StreamEncoder做編碼(自己的字符集)
     * 沒有解碼時用的字符集不兼容文件的字符集,則會產生亂碼
     *
     * @param sourceFileName
     * @param targetFileName
     */
    public static void copyFileWithInputCharset(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);
        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        InputStream inputStream;
        OutputStream outputStream;

        InputStreamReader inputStreamReader;
        OutputStreamWriter outputStreamWriter;

        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            inputStream = new FileInputStream(sourceFile);
            outputStream = new FileOutputStream(targetFile);

            //系統的字符集編碼GBK,底層通過StreamDecoder,做的流解碼
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            //StreamEncoder,做流編碼
            outputStreamWriter = new OutputStreamWriter(outputStream, "utf-8");

            bufferedReader = new BufferedReader(inputStreamReader);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                bufferedWriter.write(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void copyFileWithRandomAccessFile(String sourceFileName, String targetFileName) {
        File sourceFile = new File(sourceFileName);
        File targetFile = new File(targetFileName);
        if (!sourceFile.exists()) {
            System.out.println("文件" + sourceFileName + "不存在。");
            return;
        }
        if (!targetFile.exists()) {
            try {
                if (!targetFile.createNewFile()) {
                    System.out.println("文件" + targetFileName + "創建失敗。");
                    return;
                }
            } catch (IOException e) {
                System.out.println("文件" + targetFileName + "創建失敗。");
                e.printStackTrace();
            }
        }
        RandomAccessFile reader = null;
        RandomAccessFile writer = null;
        try {
            reader = new RandomAccessFile(sourceFile, "r");
            writer = new RandomAccessFile(targetFile, "rw");
            byte[] buffer = new byte[1 << 10];
            int len;
            //第一次的時候是零
            System.out.println("reader所在位置:"+reader.getFilePointer());
            System.out.println("writer所在位置:"+writer.getFilePointer());
            //這裏是可以調整當前位置
            reader.seek(0);
            writer.seek(0);
            while ((len = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

阻塞式I/O在java中的文件操作使用到此結束。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章