---
# System prepended metadata

title: IO
tags: [Java]

---

# Java IO
```
Java IO
-> InputStream
    -> ByteArrayInputStream
    -> FileInputStream
    -> FilterInputStream
        -> BufferedInputStream
        -> DataInputStream
-> OutputStream
    -> ByteArrayOutputStream
    -> FileOutputStream
    -> FilterOutputStream
        -> BufferedOutStream
        -> DataOutputStream
        -> PrintStream
-> Reader
    -> BufferedReader
-> Writer
    -> BufferedWriter
```
IO 即為Input/Output, 流入/流出

Stream: 我們把一組有序的資料稱為串流。

並且Java把Stream分成兩種:
- Byte Stream: InputStream/OutputStream
  不分任何類型,純的數據流。
- Char Stream: Reader/Writer (Unicode, 任何char都占用2bytes)
  按照解碼/編碼的不同,有不同的方法。

## InputStream:
- ``int read()``
  讀取下一個byte (0~255)
  如果未讀取到資料 -> return -1
- ``int read(byte b[])``
  = ``read(b,0,b.length());``
- ``int read(byte b[], int off, int len)``
  讀取最多len個byte,從``b[off]``開始存到``b[off+len]``
  回傳讀取的byte數, 如果未讀取到資料 -> return -1
- ``int available()``
  回傳inputStream中可讀取的byte數
- ``close()``
  關閉,釋放資源
- ``byte[] readAllBytes()``
  讀取所有bytes
  
### FileInputStream
讀取檔案:
```java=
FileInputStream fileInputStream = new FileInputStream(".gitignore");

int i;
while ((i = fileInputStream.read()) != -1) {
    System.out.println((char) i);
}
```
### DataInputStream
必須配合其他InputStream使用:
```java=
FileInputStream fileInputStream = new FileInputStream(".gitignore");
DataInputStream dataInputStream = new DataInputStream(fileInputStream);

dataInputStream.readInt();
dataInputStream.readUTF(); 
...
```

## OutputStream

- ``void write(int b)``
  寫入byte
- ``int write(byte b[])``
  = ``write(b,0,b.length());``
- ``int write(byte b[], int off, int len)``
  把``b[off]``到``b[off+len]``寫入
  回傳寫入的byte數, 如果未讀取到資料 -> return -1
- ``void flush()``
  刷新,並且強制寫出
- ``close()``
  關閉,釋放資源
  
### FileOutputStream
寫入檔案:
```java=
FileOutputStream fileOutputStream = new FileOutputStream(".gitignore");

byte[] data = "Hello World".getBytes();
fileOutputStream.write(data);
```
### DataOutputStream
必須配合其他OutputStream使用:
```java=
FileOutputStream fileOutputStream = new FileOutputStream(".gitignore");
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);

dataOutputStream.writeInt(300);
```
## Reader
- ``int read()``
- ``int read(char[] cbuf)``
- ``int read(char[] cbuf, int off, int len)``
- ``int skip(long n)``
- ``close()``

### InputStreamReader
用於把InputStream轉為Reader
### FileReader
繼承自InputStreamReader
```java=
FileReader fileReader = new FileReader(".gitignore");

int i;
while ((i = fileReader.read()) != -1) {
    System.out.print((char) i);
}
```
## Writer
- ``write(int c)``
- ``write(char[] cbuf)``
- ``write(char[] cbuf, int off, int len)``
- ``write(String str)``
- ``write(String str,int off, int len)``
- ``Writer append(CharSequence c)``
- ``Writer append(char c)``
- ``flush()``
- ``close()``

### OutStreamWriter
用於把OutStream轉為Writer
### FileWriter
繼承自OutStreamWriter
```java=
FileWriter fileWriter = new FileWriter(".gitignore");
fileWriter.write("Hello");
```

## BufferedStream/Reader
緩衝流, 把資料先存到buffer,一次性I/O較多資料以提升效率。

範例:
- BufferedInputStream
```java=
FileInputStream fileInputStream = new FileInputStream(".gitignore");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

int i;
while ((i = bufferedInputStream.read()) != -1) {
    System.out.print((char) i);
}
```
- BufferedReader
```java=
FileReader fileReader = new FileReader(".gitignore");
BufferedReader bufferedReader = new BufferedReader(fileReader);

int i;
while ((i = bufferedReader.read()) != -1) {
    System.out.print((char) i);
}
```
- BufferedOutputStream
```java=
FileOutputStream fileOutputStream = new FileOutputStream(".gitignore")
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

byte[] data = "Hello".getBytes();
bufferedOutputStream.write(data);
```
- BufferedWriter
```java=
FileWriter fileWriter = new FileWriter(".gitignore");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

bufferedWriter.write("Hello");
bufferedWriter.close();
```
## ``System.in`` , ``System.out``
System.in實際上是一個InputStream物件
假設我們想要從Standard Stream讀取資料:
```java=
InputStreamReader r = new InputStreamReader(System.in);
//BufferedReader reader = new BufferedReader(r);
```

System.out也是一個PrintStream, 如果需要做Logger可以對該PrintStream操作。
