InputStream中read()與read(byte[] b)
https://blog.csdn.net/snihcel/article/details/7893097
read()與read(byte[] b)這兩個方法在抽象類InputStream中前者是作為抽象方法存在的,後者不是,JDK API中是這樣描述兩者的:
1:read() :
從輸入流中讀取數據的下一個字節,返回0到255範圍內的int字節值。如果因為已經到達流末尾而沒有可用的字節,則返回-1。在輸入數據可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。
2:read(byte[] b) :
從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。以整數形式返回實際讀取的字節數。在輸入數據可用、檢測到文件末尾或者拋出異常前,此方法一直阻塞。如果 b 的長度為 0,則不讀取任何字節並返回 0;否則,嚐試讀取至少一個字節。如果因為流位於文件末尾而沒有可用的字節,則返回值 -1;否則,至少讀取一個字節並將其存儲在 b 中。將讀取的第一個字節存儲在元素
b[0] 中,下一個存儲在 b[1] 中,依次類推。讀取的字節數最多等於 b 的長度。設 k 為實際讀取的字節數;這些字節將存儲在 b[0] 到 b[k-1] 的元素中,不影響 b[k] 到 b[b.length-1] 的元素。
由幫助文檔中的解釋可知,read()方法每次隻能讀取一個字節,所以也隻能讀取由ASCII碼範圍內的一些字符。這些字符主要用於顯示現代英語和其他西歐語言。而對於漢字等unicode中的字符則不能正常讀取。隻能以亂碼的形式顯示。
對於read()方法的上述缺點,在read(byte[] b)中則得到了解決,就拿漢字來舉例,一個漢字占有兩個字節,則可以把參數數組b定義為大小為2的數組即可正常讀取漢字了。當然b也可以定義為更大,比如如果b=new
byte[4]的話,則每次可以讀取兩個漢字字符了,但是需要注意的是,如果此處定義b 的大小為3或7等奇數,則對於全是漢字的一篇文檔則不能全部正常讀寫了。
下麵用實例來演示一下二者的用法:
實例說明:類InputStreamTest1.java 來演示read()方法的使用。類InputStreamTest2.java來演示read(byte[] b)的使用。兩個類的主要任務都是通過文件輸入流FileInputStream來讀取文本文檔xuzhimo.txt中的內容,並且輸出到控製台上顯示。
先看一下xuzhimo.txt文檔的內容
InputStreamTest1.java
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest1 {
- public static void main(String[] args){
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\classes\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- int i=0;
- try {
- inputStream = new FileInputStream(file);
- while ((i = inputStream.read())!=-1){
- System.out.print((char)i + "");
- }
- }catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest1 {
- public static void main(String[] args){
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\classes\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- int i=0;
- try {
- inputStream = new FileInputStream(file);
- while ((i = inputStream.read())!=-1){
- System.out.print((char)i + "");
- }
- }catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
執行結果:

如果將while循環中的 (char)去掉,即改成:
則執行結果:

InputStreamTest2.java
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest2 {
- public static void main(String[] args){
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- int i=0;
- try {
- inputStream = new FileInputStream(file);
- byte[] bytes = new byte[16];
- while ((i = inputStream.read(bytes))!=-1){
- String str = new String(bytes);
- System.out.print(str);
- }
- }catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest2 {
- public static void main(String[] args){
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- int i=0;
- try {
- inputStream = new FileInputStream(file);
- byte[] bytes = new byte[16];
- while ((i = inputStream.read(bytes))!=-1){
- String str = new String(bytes);
- System.out.print(str);
- }
- }catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
執行結果:

遺憾的是,還是有亂碼,解決辦法可以參見下麵教程
https://wentao365.iteye.com/blog/1183951
修改後的代碼:
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest3 {
- public static void main(String[] args) {
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- String line;
- StringBuffer stringBuffer = new StringBuffer();
- try {
- //InputStream :1)抽象類,2)麵向字節形式的I/O操作(8 位字節流) 。
- inputStream = new FileInputStream(file);
- //Reader :1)抽象類,2)麵向字符的 I/O操作(16 位的Unicode字符) 。
- Reader reader = new InputStreamReader(inputStream, "UTF-8");
- //增加緩衝功能
- BufferedReader bufferedReader = new BufferedReader(reader);
- while ((line = bufferedReader.readLine()) != null) {
- stringBuffer.append(line);
- }
- if (bufferedReader != null) {
- bufferedReader.close();
- }
- String content = stringBuffer.toString();
- System.out.print(content);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest3 {
- public static void main(String[] args) {
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- InputStream inputStream = null;
- String line;
- StringBuffer stringBuffer = new StringBuffer();
- try {
- //InputStream :1)抽象類,2)麵向字節形式的I/O操作(8 位字節流) 。
- inputStream = new FileInputStream(file);
- //Reader :1)抽象類,2)麵向字符的 I/O操作(16 位的Unicode字符) 。
- Reader reader = new InputStreamReader(inputStream, "UTF-8");
- //增加緩衝功能
- BufferedReader bufferedReader = new BufferedReader(reader);
- while ((line = bufferedReader.readLine()) != null) {
- stringBuffer.append(line);
- }
- if (bufferedReader != null) {
- bufferedReader.close();
- }
- String content = stringBuffer.toString();
- System.out.print(content);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
執行結果:

還是遺憾,沒有換行。
解決辦法,通過 commons-io-*.jar
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest4 {
- public static void main(String[] args) {
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- String content = null;
- try {
- content = FileUtils.readFileToString(file, "utf-8");
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.out.println("content:" + content);
- }
- }
- /**
- * User: liuwentao
- * Time: 12-1-25 上午10:11
- */
- public class InputStreamTest4 {
- public static void main(String[] args) {
- String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";
- File file = new File(path + "xuzhimo.txt");
- String content = null;
- try {
- content = FileUtils.readFileToString(file, "utf-8");
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.out.println("content:" + content);
- }
- }
執行結果:

java InputStream讀取數據問題
https://blog.csdn.net/happyq/article/details/7992885
1. 關於InputStream.read()
在從數據流裏讀取數據時,為圖簡單,經常用InputStream.read()方法。這個方法是從流裏每次隻讀取讀取一個字節,效率會非常低。 更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次讀取多個字節。
2. 關於InputStream類的available()方法
要一次讀取多個字節時,經常用到InputStream.available()方法,這個方法可以在讀寫操作前先得知數據流裏有多少個字節可以讀取。需要注意的是,如果這個方法用在從本
地文件讀取數據時,一般不會遇到問題,但如果是用於網絡操作,就經常會遇到一些麻煩。比如,Socket通訊時,對方明明發來了1000個字節,但是自己的程序調用available()方法卻隻得到900,或者100,甚至是0,感覺有點莫名其妙,怎麼也找不到原因。其實,這是因為網絡通訊往往是間斷性的,一串字節往往分幾批進行發送。本地程序調用available()方法有時得到0,這可能是對方還沒有響應,也可能是對方已經響應了,但是數據還沒有送達本地。對方發送了1000個字節給你,也許分成3批到達,這你就要調用3次available()方法才能將數據總數全部得到。
如果這樣寫代碼:
int count = in.available();
byte[] b = new byte[count];
in.read(b);
在進行網絡操作時往往出錯,因為你調用available()方法時,對發發送的數據可能還沒有到達,你得到的count是0。
需要改成這樣:
int count = 0;
while (count == 0) {
count = in.available();
}
byte[] b = new byte[count];
in.read(b);
3. 關於InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)這兩個方法都是用來從流裏讀取多個字節的,有經驗的程序員就會發現,這兩個方法經常 讀取不到自己想要讀取的個數的字節。比如第一個方法,程序員往往希望程序能讀取到b.length個字節,而實際情況是,係統往往讀取不了這麼多。仔細閱讀Java的API說明就發現了,這個方法 並不保證能讀取這麼多個字節,它隻能保證最多讀取這麼多個字節(最少1個)。因此,如果要讓程序讀取count個字節,最好用以下代碼:
byte[] b = new byte[count];
int readCount = 0; // 已經成功讀取的字節的個數
while (readCount < count) {
readCount += in.read(bytes, readCount, count - readCount);
}
用這段代碼可以保證讀取count個字節,除非中途遇到IO異常或者到了數據流的結尾(EOFException)
最後更新:2017-04-03 18:51:44