Java 裏把 InputStream 轉換成 String 的幾種方法

 咱們在 Java 中常常會碰到如何把 InputStream 轉換成 String 的情形,好比從文件或網絡獲得一個 InputStream,須要轉換成字符串輸出或賦給別的變量。java

未真正關注這個問題以前我經常使用的辦法就是按字節一次次讀到緩衝區,或是創建 BufferedReader 逐行讀取。其實大可沒必要費此周折,咱們能夠用 Apache commons IOUtils,或者是 JDK 1.5 後的 Scanner,還可用 Google  Guava 庫的 CharStreams。到了 JDK7,若要從文件中直接獲得字符串還能用 java.nio.file.Files#readAllLines 和 java.nio.file.Files#readAllBytes 方法。android

下面看各個例子,爲可以實際用運,例子寫在 main 方法裏,並從文件得到一個 InputStream,代碼中把可能要捕獲的異常拋出來。再就是注意處理輸入輸出流時有涉及到字符集,字符集亂了就亂碼了,默認字符集是 System.getProperty("file.encoding"),一般咱們都用 UTF-8,異常 UnsupportedEncodingException 繼承自 IOException。apache

下面的 6 個方法中應該有一個你能看得上的吧,用 Groovy,Scala 的除外,若未找到一個遂意的,告訴我,你有好辦法更應該告訴我。數組

1. 使用 JDK 5 的 Scanner 網絡

package cc.unmi.test;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Scanner; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @param args      * @throws FileNotFoundException      */     public static void main(String[] args) throws FileNotFoundException {         InputStream inputStream = new FileInputStream("d:/sample.txt");         Scanner scanner = new Scanner(inputStream, "UTF-8");         String text = scanner.useDelimiter("\\A").next();         System.out.println(text);         scanner.close();     } }

2. JDK1.4 及以前的 BufferedReader 法app

package cc.unmi.test;

import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @param args      * @throws IOException      */     public static void main(String[] args) throws IOException {         InputStream inputStream = new FileInputStream("d:/sample.txt");         StringBuilder stringBuilder = new StringBuilder();         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));         boolean firstLine = true;         String line = null; ;         while((line = bufferedReader.readLine()) != null){             if(!firstLine){                 stringBuilder.append(System.getProperty("line.separator"));             }else{                 firstLine = false;             }             stringBuilder.append(line);         }         System.out.println(stringBuilder.toString());     } }

中間那些判斷是否是第一行來決定是否加換行符是些雜音。測試

3. JDK1.4 及以前的 readBytes 法ui

package cc.unmi.test;

import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @throws IOException      */     public static void main(String[] args) throws IOException {         InputStream inputStream = new FileInputStream("d:/sample.txt");                  byte[] buffer = new byte[2048];         int readBytes = 0;         StringBuilder stringBuilder = new StringBuilder();         while((readBytes = inputStream.read(buffer)) > 0){             stringBuilder.append(new String(buffer, 0, readBytes));         }                  System.out.println(stringBuilder.toString());     } }

緩衝區的大小本身根據實際來調,比 BufferedReader 還簡潔些,不需管換行符的事情。google

4. Apache commons IOUtils.toString 法編碼

package cc.unmi.test;

import java.io.*; import org.apache.commons.io.IOUtils; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @throws IOException      */     public static void main(String[] args) throws IOException {         InputStream inputStream = new FileInputStream("d:/sample.txt");         String text = IOUtils.toString(inputStream);         System.out.println(text);     } }

第三方庫就是第三方庫,人家充分考慮到了你的感覺,你對 JDK 庫的抱怨,多簡潔,一行搞定。IOUtils 還能把內容拷入其餘的 Writer 中,如 IOUtils.copy(inputStream, new StringWriter())。

5. Google guava 的  CharStreams 方法

package cc.unmi.test;

import java.io.*; import com.google.common.io.CharStreams; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @throws IOException      */     public static void main(String[] args) throws IOException {         InputStream inputStream = new FileInputStream("d:/sample.txt");         String text = CharStreams.toString(new InputStreamReader(inputStream, "UTF-8"));         System.out.println(text);     } }

CharSteams 不是直接做用在 InputSteam 上的,還要靠 InputStreamReader 拱個橋。

6. JDK 7 的 NIO readAllBytes

package cc.unmi.test;

import java.io.IOException; import java.nio.file.*; /**  *  * @author Unmi  * @Creation date: 2013-02-01  */ public class Test {     /**      * @throws IOException      */     public static void main(String[] args) throws IOException {         byte[] bytes = Files.readAllBytes(Paths.get("d:/sample.txt"));         String text = new String(bytes);         System.out.println(text);     } }

這讓咱們相信 JDK  一直還有人在管,雖然不可能象動態語言的方法那麼快捷,上面的  readAllBytes 在處理大文件時確定會很被動的。而 Files.readAllLines 會把文件的內容讀入一個 List<String> 對象中,往內存不斷放東西就得掂量下內存會不會被爆。在 java.nio.file.* 還有不少新事物可供發掘。

 

  1. /** 
  2.     * 利用BufferedReader實現Inputstream轉換成String <功能詳細描述> 
  3.     *  
  4.     * @param in 
  5.     * @return String 
  6.     */  
  7.      
  8.    public static String Inputstr2Str_Reader(InputStream in, String encode)  
  9.    {  
  10.          
  11.        String str = "";  
  12.        try  
  13.        {  
  14.            if (encode == null || encode.equals(""))  
  15.            {  
  16.                // 默認以utf-8形式  
  17.                encode = "utf-8";  
  18.            }  
  19.            BufferedReader reader = new BufferedReader(new InputStreamReader(in, encode));  
  20.            StringBuffer sb = new StringBuffer();  
  21.              
  22.            while ((str = reader.readLine()) != null)  
  23.            {  
  24.                sb.append(str).append("\n");  
  25.            }  
  26.            return sb.toString();  
  27.        }  
  28.        catch (UnsupportedEncodingException e1)  
  29.        {  
  30.            e1.printStackTrace();  
  31.        }  
  32.        catch (IOException e)  
  33.        {  
  34.            e.printStackTrace();  
  35.        }  
  36.          
  37.        return str;  
  38.    }  
  39.      
  40.    /** 
  41.     * 利用byte數組轉換InputStream------->String <功能詳細描述> 
  42.     *  
  43.     * @param in 
  44.     * @return 
  45.     * @see [類、類#方法、類#成員] 
  46.     */  
  47.      
  48.    public static String Inputstr2Str_byteArr(InputStream in, String encode)  
  49.    {  
  50.        StringBuffer sb = new StringBuffer();  
  51.        byte[] b = new byte[1024];  
  52.        int len = 0;  
  53.        try  
  54.        {  
  55.            if (encode == null || encode.equals(""))  
  56.            {  
  57.                // 默認以utf-8形式  
  58.                encode = "utf-8";  
  59.            }  
  60.            while ((len = in.read(b)) != -1)  
  61.            {  
  62.                sb.append(new String(b, 0, len, encode));  
  63.            }  
  64.            return sb.toString();  
  65.        }  
  66.        catch (IOException e)  
  67.        {  
  68.            e.printStackTrace();  
  69.        }  
  70.        return "";  
  71.          
  72.    }  
  73.      
  74.    /** 
  75.     * 利用ByteArrayOutputStream:Inputstream------------>String <功能詳細描述> 
  76.     *  
  77.     * @param in 
  78.     * @return 
  79.     * @see [類、類#方法、類#成員] 
  80.     */  
  81.    public static String Inputstr2Str_ByteArrayOutputStream(InputStream in,String encode)  
  82.    {  
  83.        ByteArrayOutputStream out = new ByteArrayOutputStream();  
  84.        byte[] b = new byte[1024];  
  85.        int len = 0;  
  86.        try  
  87.        {  
  88.            if (encode == null || encode.equals(""))  
  89.            {  
  90.                // 默認以utf-8形式  
  91.                encode = "utf-8";  
  92.            }  
  93.            while ((len = in.read(b)) > 0)  
  94.            {  
  95.                out.write(b, 0, len);  
  96.            }  
  97.            return out.toString(encode);  
  98.        }  
  99.        catch (IOException e)  
  100.        {  
  101.            e.printStackTrace();  
  102.        }  
  103.        return "";  
  104.    }  
  105.      
  106.    /** 
  107.     * 利用ByteArrayInputStream:String------------------>InputStream <功能詳細描述> 
  108.     *  
  109.     * @param inStr 
  110.     * @return 
  111.     * @see [類、類#方法、類#成員] 
  112.     */  
  113.    public static InputStream Str2Inputstr(String inStr)  
  114.    {  
  115.        try  
  116.        {  
  117.            // return new ByteArrayInputStream(inStr.getBytes());  
  118.            // return new ByteArrayInputStream(inStr.getBytes("UTF-8"));  
  119.            return new StringBufferInputStream(inStr);  
  120.        }  
  121.        catch (Exception e)  
  122.        {  
  123.            e.printStackTrace();  
  124.        }  
  125.        return null;  
  126.    }  

=====================================

Android讀取txt文件亂碼解決方案:
讀取inputsteam的時候以 GB2312」方式讀取,注意單純的利用retStr =EncodingUtils.getString(retStr.getBytes(), "GB2312");是不行的,實例化retStr的時候就應該以「GB2312」方式。
如下是轉載的內容:
從SDCard保存的txt文件讀取中文到android系統中會出現亂碼問題,如何解決這個亂碼問題,網上有很多解答方法,譬如說利用String temp1 =EncodingUtils.getString(strLine.getBytes(),"GB2312"); 但並不是對全部的狀況都適用,解決亂碼問題首先要明白爲何會亂碼。究其緣由,是由於txt文件在win系統上保存時默認爲ANSI格式,而android目前只支持UTF-8編碼,所以將txt文件的中文讀入android系統中會產生亂碼。也有人說直接將txt另存爲UTF-8編碼格式來解決亂碼問題,但這種方法指標不治本,不能要求用戶手動去更改格式,客戶第一嘛。所以仍是須要想辦法在程序中進行處理。
如下作了一些編碼格式的測試:

測試文本: 122.11196,29.90573,北侖固廢廠 測試代碼段:

reader=new BufferedReader(new FileReader(filename));

strLine=reader.readLine() ;

String temp1 = EncodingUtils.getString(strLine.getBytes(),"GB2312");

String temp2 = EncodingUtils.getString(strLine.getBytes("utf-8"),"utf-8");

String temp3 = EncodingUtils.getString(strLine.getBytes(),"utf-8");

將文件存成 Unicode 格式

將文件存成utf-8 格式

這種方式能獲得非亂碼的中文顯示,但對於 utf-8 格式下取得的經緯度數字利用double lon = Double.parseDouble(lat); 報錯 NumberFormatException,緣由多是 parseDouble(lat)方法不能處理存成utf-8格式的帶標點小數。 將文件 存成 ANSI 格式

將代碼改成:

 

reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename),"GB2312"));

 

strLine=reader.readLine() ;

 

String temp1 = EncodingUtils.getString(strLine.getBytes(),"GB2312");

 

String temp2 = EncodingUtils.getString(strLine.getBytes("utf-8"),"utf-8");

 

String temp3 = EncodingUtils.getString(strLine.getBytes(),"utf-8");

即解決了中文亂碼問題,又解決了Double.parseDouble(lat)報錯問題。

相關文章
相關標籤/搜索