IO操做

原文連接http://zhhll.icu/2020/05/18/java%E5%9F%BA%E7%A1%80/IO/java%E5%9F%BA%E7%A1%80%E4%B9%8BIO%E6%93%8D%E4%BD%9C/java

用戶進程發起請求,內核接收到請求後,從I/O設備中獲取數據到buffer中,再將buffer中的數據copy到用戶進程的地址空間,該用戶進程獲取到數據後再響應客戶端。編程

數據輸入到buffer須要時間,從buffer複製數據至進程也須要時間,根據在這兩段時間內等待方式不一樣,I/O動做可分爲五種模式數組

  • 阻塞I/O(Blocking I/O)
  • 非阻塞I/O(Non-Blocking I/O)
  • I/O複用(I/O Multiplexing)
  • 信號驅動I/O
  • 異步I/O

java的I/O操做在類的java.io包中網絡

  • 基於字節操做的I/O接口: InputStream和OutputStream多線程

  • 基於字符操做的I/O接口: Writer和Readerdom

  • 基於磁盤操做的I/O接口: File異步

  • 基於網絡操做的I/O接口: Socket(網絡編程,不在io包中)性能

普通IO

  1. 字節流對應原生的二進制數據優化

  2. 字符流對應字符數據,會自動處理與本地字符集之間的轉換線程

  3. 緩衝流能夠提升性能,經過減小底層API的調用次數來優化IO

字節流

輸入流

字節輸入流都繼承自InputStream,InputStream表示從不一樣數據源產生輸入的類,這些數據員包括

  1. 字節數組
  2. String對象
  3. 文件
  4. 管道,從一端輸入,從另外一端輸出
  5. 一個由其餘種類的流組成的序列,而後把它們匯聚爲一個流
  6. 其餘數據源,如Internet鏈接
功能 構造器 如何使用
ByteArrayInputStream 容許將內存的緩衝區當作InputStream使用 緩衝區,字節將從中取出 將其與FilterInputStream對象相連以提供有用接口
StringBufferInputStream 將String轉換爲InputStream 字符串。底層實現實際使用StringBuffer 將其與FilterInputStream對象相連以提供有用接口
FileInputStream 用於從文件中讀取信息 字符串,表示文件名、文件或FileDescriptor對象
PipedInputStream 產生用於寫入相關PipedOutputStream的數據。實現管道化概念 PipedOutputStream 做爲多線程中的數據源
SequenceInputStream 將兩個或多個InputStream對象轉換成一個InputStream 兩個InputStream對象或一個容納InputStream對象的容器Enumeration
FilterInputStream 抽象類,做爲裝飾器的接口,爲其餘的InputStream類提供有用的功能

FilterInputStream類型子類包括如下幾種

功能 構造器 如何使用
DataInputStream 與DataOutputStream搭配使用,按照移植方式從流讀取基本數據類型 InputStream 包含用於讀取基本數據類型的所有接口
BufferedInputStream 使用它能夠防止每次讀取時都得進行實際寫操做 InputStream 本質上不提供接口,只是向進程添加緩衝功能
LineNumberInputStream 跟蹤輸入流的行號,可調用getLineNumber()和setLineNumber(int) InputStream,能夠指定緩衝區大小 僅增長了行號
PushbackInputStream 具備能彈出一個字節的緩衝區,所以能夠將讀到的最後一個字符回退 InputStream 一般做爲編譯器的掃描器

輸出流

字節輸入流都繼承自OuputStream,該類決定了輸出所要去的目標,字節數組、文件或管道

功能 構造器 如何使用
ByteArrayOutputStream 在內存中建立緩衝區。全部送往流的數據都要放置在此緩衝區 緩衝區初始大小 用於指定數據的目的地
FileOutputStream 用於將信息寫入文件 字符串,表示文件名、文件或FileDescriptor對象
PipedOutputStream 任何寫入其中的信息都會自動做爲相關PipedInputStream的輸出,實現管道化概念 PipedInputStream 指定用於多線程的數據的目的地
FilterOutputStream 抽象類,做爲裝飾器的接口,爲其餘OutputStream提供有用的功能

FilterOutputStream類型子類包括

功能 構造器 如何使用
DataOutputStream 與DataInputStream搭配使用,能夠按照移植方式向流中寫入基本數據類型 OutputStream 包含用於寫入基本數據類型的所有接口
PrintStream 用於產生改格式化輸出。其中DataOutputStream處理數據的存儲,PrintStream處理顯示 OutputStream,能夠用boolean值指示是否每次換行時清空緩衝區 應該是對OutputStream對象的final封裝
BufferedOutputStream 使用它以免每次發送數據時都進行實際的寫操做,能夠調用flush()清空緩衝區 OutputStream,能夠指定緩衝區大小 只是向進程添加緩衝功能

字符流

InputStream和OutputStream是面向字節I/O的,而Reader和Writer則提供兼容Unicode和麪向字符I/O的功能,InputStreamReader能夠把InputStream轉換爲Reader,而OutputStreamWriter能夠把OutputStream轉換爲Writer

RandomAccessFile類

適用於由大小已知的記錄組成的文件,可使用seek()將文件指針從一條記錄移動到另外一條記錄,而後對記錄進行讀取和修改。文件中記錄的大小不必定相同,只要咱們能肯定那些記錄有多大以及它們在文件中的位置便可。

RandomAccessFile類不是InputStream或者OutputStream的子類,只是實現了DataInput和DataOutput接口,沒有使用InputStream和OutputStream的任何功能,全部方法都是獨立的,大部分爲native方法

經常使用的IO操做

緩衝輸入文件

想要打開一個文件進行字符輸入,可使用FileReader對象,而後傳入一個String或者File對象做爲文件名。爲了提升速度,對文件進行緩衝,能夠將所產生的引用傳遞給一個BufferedReader構造器。BufferedReader提供了lines()方法,會產生一個Stream 對象

public static void read(String file) {
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){
            String line = null;
            while((line = bufferedReader.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            throw new RuntimeException("讀取失敗",e);
        }
    }

讀取字符

public static void read() throws IOException {
        StringReader stringReader = new StringReader("qaw試試");
        int c;
        while ((c = stringReader.read()) != -1) {
            System.out.println((char)c);
        }
    }

StringReader的read方法是以int形式返回的下一個字節,因此打印的時候類型必須轉爲char

格式化數據

要讀取格式化數據,可使用DataInputStream,是面向字節的,因此要使用InputStream類

文件輸出

FileWrite對象用於向文件寫入數據,一般使用BufferedWriter將其包裝起來增長緩衝的功能,

try(BufferedReader in = new BufferedReader(new StringReader("1111111111111111\n2222222222222\n3333333333"));
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter("test.txt")))
        ){
            in.lines().forEach(printWriter :: println);
        } catch (IOException e) {
            e.printStackTrace();
        }

標準IO

標準輸入流Systom.in、標準輸出流System.out、標準錯誤流Sytem.err。

System.out和System.err是預先包裝成了PrintStream對象,可是System.in沒有進行包裝,屬於原生的InputStream,因此在讀取時須要對其進行包裝

標準輸入

一般一行一行地讀取輸入,將System.in包裝成BufferedReader

public static void main(String[] args) {
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                if (line.equals("end")) {
                    break;
                }
                System.out.println(line);
            }
        } catch (IOException e) {

        }
    }

重定向標準I/O

System類提供了簡單的靜態方法調用,重定向標準輸入流、標準輸出流和標準錯誤流

  • setIn(InputStream)

  • setOut(PrintStream)

  • setErr(PrintStream)

public static void main(String[] args) {
        try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("C:\\Users\\sinosoft\\Desktop\\剩餘工做.txt"));
            PrintStream printStream = new PrintStream(new BufferedOutputStream(new FileOutputStream("C:\\Users\\sinosoft\\Desktop\\剩餘工做副本.txt")))
        ){
            System.setIn(bufferedInputStream);
            System.setOut(printStream);
            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    if (line.equals("end")) {
                        break;
                    }
                    System.out.println(line);
                }
            } catch (IOException e1) {

            }
        }catch (IOException e){

        }
    }

因爲自己的博客百度沒有收錄,博客地址http://zhhll.icu

相關文章
相關標籤/搜索