概述
什么是IO?
IO就是輸入流輸出流的意思,以記憶體為基準,分為輸入input 和輸出output ,即流向記憶體是輸入流,流出記憶體的輸出流,
- 輸入流:把硬碟中的資料讀取到記憶體中使用
- 輸出流:把記憶體中的資料寫入到硬碟中保存

上方的表格是頂級父類
位元組流
一切皆位元組
一切檔案資料(文本、圖片、視頻等)在存盤時,都是以二進制數字的形式保存,都一個一個的位元組,那么傳輸時一樣如此,
所以,位元組流可以傳輸任意檔案資料,在操作流的時候,我們要時刻明確,無論使用什么樣的流物件,底層傳輸的始終為二進制資料,
位元組輸入流(InputStream)
java.io.InputStream ``抽象類是表示位元組輸入流的所有類的超類,可以讀取位元組資訊到記憶體中,
它定義了位元組輸入流的基本共性功能方法,
public abstract int read(): 從輸入流讀取資料的下一個位元組,public int read(byte[] b): 從輸入流中讀取一些位元組數,并將它們存盤到位元組陣列 b中 ,public void close():關閉此輸入流并釋放與此流相關聯的任何系統資源,
檔案位元組輸入流(FileInputStream)
java.io.FileInputStream 類是檔案輸入流,繼承InputStream抽象類,publicclass FileInputStream extends InputStream
作用是把硬碟檔案中的資料,讀取到記憶體中使用,
讀取資料的原理(硬碟->記憶體):Java程式-->JVM-->作業系統-->呼叫本地方法-->讀取檔案內容
構造方法
| Constructor | Description |
|---|---|
FileInputStream(File file) * |
通過打開與實際檔案的連接創建一個 FileInputStream ,該檔案由檔案系統中的 File物件 file命名, |
FileInputStream(String name) |
通過打開與實際檔案的連接來創建一個 FileInputStream ,該檔案由檔案系統中的路徑名 name命名, |
FileInputStream(FileDescriptor fdObj) |
創建 FileInputStream通過使用檔案描述符 fdObj ,其表示在檔案系統中的現有連接到一個實際的檔案, |
當你創建一個流物件時,必須傳入一個檔案路徑,該路徑下,如果沒有該檔案,會拋出FileNotFoundException ,
常用方法
| 方法 | 描述 |
|---|---|
| int read() | 從此輸入流中讀取一個資料位元組, |
| int read(byte[] b) | 從此輸入流中將最多 b.length 個位元組的資料讀入一個 byte 陣列中, |
| int read(byte[] b, int off, int len) | 從此輸入流中將最多 len 個位元組的資料讀入一個 byte 陣列中, |
| void close() | 關閉此檔案輸入流并釋放與此流有關的所有系統資源, |
| long skip(long n) | 從輸入流中跳過并丟棄 n 個位元組的資料, |
| protected void finalize() | 確保在不再參考檔案輸入流時呼叫其 close 方法, |
| int available() | 回傳下一次對此輸入流呼叫的方法可以不受阻塞地從此輸入流讀取(或跳過)的估計剩余位元組數, |
| FileChannel getChannel() | 回傳與此檔案輸入流有關的唯一 FileChannel 物件, |
| FileDescriptor getFD() | 回傳表示到檔案系統中實際檔案的連接的 FileDescriptor 物件,該檔案系統正被此 FileInputStream 使用, |
*在檔案位元組輸入流中,read()底層呼叫本地方法read0()
其他兩個read方法呼叫本地方法readBytes(byte b[], int off, int len)
使用步驟
- 創建FileInputStream物件,構造方法中系結資料源
- 使用FileInputStream物件中的read方法,讀取資料
- 釋放資源
package IO;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStream_in {
public static void main(String args[]) throws IOException{
//read("1.txt");
//readMore("1.txt");
readAll("1.txt");
}
public static void read(String path) throws IOException{
FileInputStream fis = new FileInputStream(path);
int len =0;
while((len = fis.read())!=-1)
System.out.print((char)len);
fis.close();
}
public static void readMore(String path) throws IOException{
FileInputStream fis = new FileInputStream(path);
int len =0;
byte[] bytes = new byte[2];
while((len = fis.read(bytes))!=-1)
System.out.println(new String(bytes));
fis.close();
}
//優化上一個方法
public static void readAll(String path) throws IOException{
FileInputStream fis = new FileInputStream(path);
int len =0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1)
System.out.print(new String(bytes,0,len));//只取有效部分
fis.close();
}
}
位元組輸出流(OutputStream)
java.io.OutputStream 抽象類是表示位元組輸出流的所有類的超類,將指定的位元組資訊寫出到目的地,
它定義了位元組輸出流的基本共性功能方法,
public void close():關閉此輸出流并釋放與此流相關聯的任何系統資源,public void flush():重繪此輸出流并強制任何緩沖的輸出位元組被寫出,public void write(byte[] b):將 b.length位元組從指定的位元組陣列寫入此輸出流,public void write(byte[] b, int off, int len):從指定的位元組陣列寫入 len位元組,從偏移量 off開始輸出到此輸出流,public abstract void write(int b):將指定的位元組輸出流,

| 方法 | 描述 |
|---|---|
| void close() | 關閉此輸出流并釋放與此流有關的所有系統資源, |
| void flush() | 重繪此輸出流并強制寫出所有緩沖的輸出位元組, |
| void write(byte[] b) | 將 b.length 個位元組從指定的 byte 陣列寫入此輸出流, |
| void write(byte[] b, int off, int len) | 將指定 byte 陣列中從偏移量 off 開始的 len 個位元組寫入此輸出流, |
| abstract void write(int b) | 將指定的位元組寫入此輸出流, |
*在位元組輸出流中,write的多載方法都呼叫write(int b) 方法
檔案位元組輸出流(FileOutputStream)
java.io.FileInputStream 類是檔案輸入流,從檔案中讀取位元組,
寫入資料的原理(記憶體->硬碟):Java程式-->JVM-->作業系統-->呼叫本地方法-->把資料寫入檔案
構造方法
FileInputStream(File file): 通過打開與實際檔案的連接來創建一個 FileInputStream ,該檔案由檔案系統中的 File物件 file命名,FileInputStream(String name): 通過打開與實際檔案的連接來創建一個 FileInputStream ,該檔案由檔案系統中的路徑名 name命名,
當你創建一個流物件時,必須傳入一個檔案路徑,該路徑下,如果沒有該檔案,會拋出FileNotFoundException ,
| Constructor | Description |
|---|---|
FileOutputStream(File file, boolean append) ** |
創建檔案輸出流以寫入由指定的 File物件表示的檔案, |
FileOutputStream(String name, boolean append) |
創建檔案輸出流以指定的名稱寫入檔案,append是追加開關,默認false(關), |
FileOutputStream(String name) |
創建檔案輸出流以指定的名稱寫入檔案, |
FileOutputStream(File file) |
創建檔案輸出流以寫入由指定的 File物件表示的檔案, |
FileOutputStream(FileDescriptor fdObj) * |
創建檔案輸出流以寫入指定的檔案描述符,表示與檔案系統中實際檔案的現有連接, |
其實不管哪個構造器都轉成FileOutputStream(File file, boolean append)形式
常用方法
| 方法 | 描述 |
|---|---|
| void write(int b) **核心 | 將指定位元組寫入此檔案輸出流, |
| void write(byte[] b) | 將 b.length 個位元組從指定 byte 陣列寫入此檔案輸出流中, |
| void write(byte[] b, int off, int len) | 將指定 byte 陣列中從偏移量 off 開始的 len 個位元組寫入此檔案輸出流, |
| void close() | 關閉此檔案輸出流并釋放與此流有關的所有系統資源, |
| protected void finalize() | 清理到檔案的連接,并確保在不再參考此檔案輸出流時呼叫此流的 close 方法, |
| FileChannel getChannel() | 回傳與此檔案輸出流有關的唯一FileChannel 物件, |
| FileDescriptor getFD() | 回傳與此流有關的檔案描述符, |
底層呼叫本地(native)方法write(int b, boolean append)和writeBytes(byte b[], int off, int len, boolean append)
在檔案位元組輸出流中,write多載方法呼叫不同的本地方法,
實體
//用檔案位元組輸出流向檔案寫入一個位元組
import java.io.*;
public class fileIO {
public static void main(String args[]) throws IOException{
FileOutputStream fos = new FileOutputStream("1.txt");
fos.write(97);//輸入一個位元組 97的二進制1100001
fos.close();//打開記事本默認讀字符97對應的ASCII表是a
}
}

package IO;
import java.io.*;
import java.util.Arrays;
public class FileOutputStream_ {
public static void main(String args[]) throws IOException{
fileOutOne("1.txt",97);//向1檔案寫入1個位元組(8位)01100001
byte[] t = "你好".getBytes();
System.out.println(Arrays.toString(t)); //gdk中英都占兩個位元組, utf-8 英文一位元組,中文三位元組
fileOutMore("2.txt",t);//向2檔案寫入你好字串轉化的位元組陣列,
byte[] b = {97,98,49,48,48};
fileOutMore1("3.txt",b);//向3檔案寫入一個規定位元組陣列,
}
//使用位元組輸出流向檔案寫入一個位元組
public static void fileOutOne(String path,int num) throws IOException{
FileOutputStream fos = new FileOutputStream(path);//指向路徑的檔案
fos.write(num);//輸入一個位元組 97的二進制1100001
fos.close();//打開記事本默認讀字符97對應的ASCII表是a
}
//使用位元組輸出流向檔案寫入多個位元組
public static void fileOutMore(String path,byte[] bytes) throws IOException{
File f = new File(path);
FileOutputStream fos = new FileOutputStream(f);//指向具體檔案
fos.write(bytes);//寫入一個位元組陣列
fos.close();
}
//使用位元組輸出流向檔案寫入偏移的多個位元組
public static void fileOutMore1(String path,byte[] bytes) throws IOException{
File f = new File(path);
FileOutputStream fos = new FileOutputStream(f);//指向具體檔案
//byte[] b = {97,98,49,48,48}; 本應該是 ab100 偏移兩位,寫入三位得100
fos.write(bytes,2,3);//輸入一個位元組陣列
fos.close();
}
}
追加 和 換行
package IO;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStrean_append {
public static void main(String args[]) throws IOException{
fileOutAppend("1.txt","append".getBytes());//向1檔案追加換行和寫入一個單詞
}
public static void fileOutAppend(String path,byte[] bytes) throws IOException{
FileOutputStream fos = new FileOutputStream(path,true);//true 標記追加
fos.write("\r\n".getBytes());//window系統下檔案的換行符號
fos.write(bytes);//寫入一個位元組陣列
fos.close();
}
}
復制檔案
步驟
- 創建一個位元組輸入流物件,構造方法中系結要讀取的資料源
- 創建一個位元組輸出流物件,構造方法中系結要寫入的目的地
- 使用位元組輸入流物件的read方法讀取資料
- 使用直接輸出流物件的write方法將讀取到的資料寫入目的地檔案
- 釋放資源(堆疊順序,先進后出)
package bytestream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) throws IOException {
// 1. 創建一個位元組輸入流物件,構造方法中系結要讀取的資料源
FileInputStream fis = new FileInputStream("test.txt");
// 2. 創建一個位元組輸出流物件,構造方法中系結要寫入的目的地
FileOutputStream fos = new FileOutputStream("test2.txt");
// 3. 使用位元組輸入流物件的read方法讀取資料
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
// 4. 使用直接輸出流物件的write方法將讀取到的資料寫入目的地檔案
fos.write(bytes, 0, len);
}
// 5. 釋放資源(堆疊順序,先進后出)
fos.close();
fis.close();
}
}
問題
中文字符的編碼
- GBK 占兩位元組
- UTF-8 占三個位元組
package bytestream;
import java.io.FileInputStream;
import java.io.IOException;
public class ByteStreamTest {
public static void main(String[] args) throws IOException {
// 當使用位元組流讀取字符時,存在一些問題
FileInputStream fis = new FileInputStream("test.txt");
int len = 0;
while ((len = fis.read()) != -1) {
System.out.println((char)len);
}
fis.close();
}
}
test.txt
123789456你好
運行結果
1
2
3
7
8
9
4
5
6
?
?
?
¥
?
使用位元組流讀取字符資料出現亂碼!
位元組流存在的問題:當使用位元組流讀取文本檔案時,可能會有一個小問題,就是遇到中文字符時,可能不會顯示完整的字符,
那是因為一個中文字符可能占用多個位元組存盤,所以Java提供一些字符流類,以字符為單位讀寫資料,專門用于處理文本檔案,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/177274.html
標籤:Java
下一篇:Java - IO - 字符流
