java 字节输入流_JavaIO流(一)-字节输入流与字符输入流
IO流詳解
一、輸入流
字節輸入流
FileInputSteam
1、構造方法:public FileInputStream(File file) {}
public FileInputStream(FileDescriptor fdObj){}
public FileInputStream(String name){}
2、read方法:// 每次讀取一個字節
public int read(){}
// 讀取b.length個字節到byte數組中
public int read(byte b[]){}
// 從輸入流中讀取len個字節到字節數組中
public int read(byte b[], int off, int len){}
3、文件讀取:
1、read()每次讀取一個字節數據,返回字節數,如果到達文件末尾,返回-1。
文本abcpublic static void method_01(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 每次讀取一個字節
for (int i = 0; i < 4; i++) {
int read = inputStream.read();
System.out.println(read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
// 關閉IO流
inputStream.close();
}
}
}
執行結果:97
98
99
-1
從執行結果可以看出,前三次讀取到了數據,返回了對應的ASCII碼,當讀取到文件末尾的時候,則返回-1。
2、read(byte[] b)讀入緩沖區的字節總數,如果到達文件末尾,則返回-1。
文本:abcdefg
聲明一個大于真實數據的byte數組讀取數據。public static void method_02(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 聲明的長度大于真實數據長度
byte[] bytes = new byte[20];
int length = inputStream.read(bytes);
System.out.println("字節數組長度:" + bytes.length + " 讀取到的數據字節長度:" + length);
for (byte b : bytes) {
System.out.print(b + " | ");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
執行結果:字節數組長度:20 讀取到的數據字節長度:7
97 | 98 | 99 | 100 | 101 | 102 | 103 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
可以看出,當我們byte數組的長度大于字節數組的真實長度之后,那么后面的空間全部使用0做補位,這也恰恰反映了另外一個問題,我們在使用byte[]數組讀取文件的時候,千萬不要說我設置足夠大的長度,就可以高枕無憂提高讀取效率,如果遇到小文件,那么也是很容易造成效率低下的。
3、read(byte b[], int off, int len)讀入緩沖區的字節總數,如果讀取到文件末尾,則返回-1;
文本:abcdefg
聲明一個固定大小的byte數組,循環讀取數據
我們的文本有七個字節,聲明了一個2個長度的數組,應該循環四次,第五次讀取的時候返回-1。public static void method_03(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 聲明2個長度
byte[] bytes = new byte[2];
int i = 0;
while (i < 5) {
int length = inputStream.read(bytes, 0, bytes.length);
System.out.println("第" + (i + 1) + "次讀取,length: " + length);
System.out.println("開始輸出:");
for (int j = 0; j < length; j++) {
System.out.print(bytes[j] + " | ");
}
System.out.println();
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
執行結果:第1次讀取,length: 2
開始輸出:
97 | 98 |
第2次讀取,length: 2
開始輸出:
99 | 100 |
第3次讀取,length: 2
開始輸出:
101 | 102 |
第4次讀取,length: 1
開始輸出:
103 |
第5次讀取,length: -1
開始輸出:
注意:
可能有的朋友會遇到我之前遇到的問題,他的文本里面寫了漢字或者標點符號,會出現亂碼,我們給文本最后再追加一個中文,并且把每次讀取到的byte數組轉換成String進行輸出,看會出現什么情況。public static void method_03(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
byte[] bytes = new byte[2];
int i = 0;
while (i < 5) {
inputStream.read(bytes, 0, bytes.length);
// 將byte[]轉換成string
String s = new String(bytes, StandardCharsets.UTF_8);
System.out.println(s);
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
結果:ab
cd
ef
g�
��
剛開始腦子抽了,感覺這是什么問題,怎么會亂碼呢,如果稍微上點心的都會發現,中文占3個byte字節,你用2個存儲那鐵定亂碼呀。那么你肯定想過那我把數組聲明大一點不就好了,如果你這么想過,那你可能還不知道社會的險惡。
那么到底怎么辦呢?真的就沒辦法了嗎?接下來我們用一個例子來學習如何解決這種問題。
一個🌰:將文本中的內容讀取出來,輸出到控制臺。
既然我們知道,上面的亂碼是因為英文和中文占用的字節數不同引起的,那我們要是知道了整個文件占用的字節長度,那么不就一次性可以讀取出來了。恰好FileInputStream提供了這樣一個方法(available),讓我們可以獲取到整個文件所占用的字節數。public static void printConsole(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 獲取到整個文本占用的整個字節數
int available = inputStream.available();
// 聲明數組
byte[] bytes = new byte[available];
// 讀取數據
int readLength = inputStream.read(bytes, 0, available);
String s = new String(bytes, StandardCharsets.UTF_8);
System.out.println("讀取到的長度:" + readLength + " available:" + available);
System.out.println("讀取到的內容: " + s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
結果:讀取到的長度:30 available:30
讀取到的內容: abcdef一個程序員的成長
這樣的話,我們就可以讀取到文本中完整的內容了。只有了解了這些,那么才會了解我們的寫文件下載的時候為什么要判斷 讀取到的字節數 !=-1 這樣的操作,不然真的很難記住。
字符輸入流
FileReader
1、構造方法:public FileReader(String fileName){};
public FileReader(File file){};
public FileReader(FileDescriptor fd){};
2、read方法:public int read(){};
public int read(char cbuf[], int offset, int length){};
public int read(char cbuf[]){};
3、文件讀取:
FileReader的read方法讀取出來的是一個獨立的字符(char),所以面對英文和中文的混合,我們不會因為占用字節的不同從而導致出現亂碼的情況。
文本:abcdef一個程序員的成長
讀取內容的代碼:public static void method_01(String filePath) throws IOException {
FileReader fr = null;
try {
fr = new FileReader(filePath);
int c;
// 每次讀取一個字符,等于-1即表示文件讀取到末尾
while ((c = fr.read()) != -1) {
System.out.println((char) c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != fr) {
fr.close();
}
}
結果:a
b
c
d
e
f
一
個
程
序
員
的
成
長
根據結果可以看出,read()讀取出來的每次就是一個單獨的字符,那么另外兩個read方法跟字節流讀取都是一樣的。
更多內容請關注微信公眾號:
總結
以上是生活随笔為你收集整理的java 字节输入流_JavaIO流(一)-字节输入流与字符输入流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浦发AE白额度最低多少?最高额度多少?
- 下一篇: java编程能做什么_学习Java编程能