Java 里把 InputStream 转换成 String 的几种方法

我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量。

未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取。其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google  Guava 库的 CharStreams。到了 JDK7,若要从文件中直接得到字符串还能用 java.nio.file.Files#readAllLines 和 java.nio.file.Files#readAllBytes 方法。

下面看各个例子,为能够实际用运,例子写在 main 方法里,并从文件获得一个 InputStream,代码中把可能要捕获的异常抛出来。再就是注意处理输入输出流时有涉及到字符集,字符集乱了就乱码了,默认字符集是 System.getProperty("file.encoding"),通常我们都用 UTF-8,异常 UnsupportedEncodingException 继承自 IOException。

下面的 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 法

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 法

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 还简洁些,不需管换行符的事情。

本文原始链接: http://unmi.cc/java-convert-inputstream-to-string , 来自: 隔叶黄莺 Unmi Blog

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

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

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)报错问题。

时间: 2025-01-02 18:22:08

Java 里把 InputStream 转换成 String 的几种方法的相关文章

Java 把 InputStream 转换成 String 的几种方法

我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量. 未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取.其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google  Guava 库的 CharStreams.到了 JDK7,

[Java类型转换] Object 转换成 String 的三种方法

方法一:Object.toString() obj.toString() 注意:必须保证Object不是null值,否则将抛出NullPointerException异常. 方法二:(String)Object Object o = new Integer(100); String string = (String)o; 注意:需要转换的类型必须是能够转换为String的,否则会出现CalssCastException异常错误. 方法三:String.valueOf(Object) 在使用Str

DataTable 转换成 Json的3种方法

在web开发中,我们可能会有这样的需求,为了便于前台的JS的处理,我们需要将查询出的数据源格式比如:List<T>.DataTable转换为Json格式.特别在使用Extjs框架的时候,Ajax异步请求的数据格式就是Json.鉴于此,我今天来分享将DataTable 转换成 Json的3种方法.换句话说如何在ASP.NET将一个DataTable序列化为 Json数组.或者如何从一个DataTable返回一个Json字符串.这篇文章将采用StringBuilder,JavaScriptSeri

Spark中将RDD转换成DataFrame的两种方法

总结下Spark中将RDD转换成DataFrame的两种方法, 代码如下: 方法一: 使用createDataFrame方法 ```java //StructType and convert RDD to DataFrame val schema = StructType( Seq( StructField("name",StringType,true) ,StructField("age",IntegerType,true) ) ) val rowRDD = sp

js 字符串转换成数字的三种方法

在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形式的.在网上找了一下js字符串转数字的文章,这个比较全 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才

JavaScript字符串转换成数字的三种方法

在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形式的.在网上找了一下js字符串转数字的文章,这个比较全 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才

js 字符串转换成数字的三种方法--转

在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形式的.在网上找了一下js字符串转数字的文章,这个比较全 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才

字符串转换成数字的三种方法

1.转换函数,利用parseInt()和parseFloat()两个转换函数. 2.强制类型转换. Boolean(value)——把给定的值转换成Boolean型:    Number(value)——把给定的值转换成数字(可以是整数或浮点数):    String(value)——把给定的值转换成字符串. 3.利用js变量弱类型转换 var s="9.90"; console.log(typeof (s-1)); console.log(typeof (s*1));

python将字符串转换成字典的几种方法

当我们遇到类似于{'a':1, 'b':2, 'c':3}这种字符串时,想要把它转换成字典进行处理,可以使用以下几种方法: 1. Python自带的eval函数(不安全) dictstr = '{"a":1, "b":2, "c":{"d":1}}' mydict = eval(dictstr) 2.使用 ast 模块的 literal_eval 函数(安全) dictstr = '{"a":1, &quo