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 还简洁些,不需管换行符的事情。
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.* 还有很多新事物可供发掘。
- /**
- * 利用BufferedReader实现Inputstream转换成String <功能详细描述>
- *
- * @param in
- * @return String
- */
- public static String Inputstr2Str_Reader(InputStream in, String encode)
- {
- String str = "";
- try
- {
- if (encode == null || encode.equals(""))
- {
- // 默认以utf-8形式
- encode = "utf-8";
- }
- BufferedReader reader = new BufferedReader(new InputStreamReader(in, encode));
- StringBuffer sb = new StringBuffer();
- while ((str = reader.readLine()) != null)
- {
- sb.append(str).append("\n");
- }
- return sb.toString();
- }
- catch (UnsupportedEncodingException e1)
- {
- e1.printStackTrace();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return str;
- }
- /**
- * 利用byte数组转换InputStream------->String <功能详细描述>
- *
- * @param in
- * @return
- * @see [类、类#方法、类#成员]
- */
- public static String Inputstr2Str_byteArr(InputStream in, String encode)
- {
- StringBuffer sb = new StringBuffer();
- byte[] b = new byte[1024];
- int len = 0;
- try
- {
- if (encode == null || encode.equals(""))
- {
- // 默认以utf-8形式
- encode = "utf-8";
- }
- while ((len = in.read(b)) != -1)
- {
- sb.append(new String(b, 0, len, encode));
- }
- return sb.toString();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return "";
- }
- /**
- * 利用ByteArrayOutputStream:Inputstream------------>String <功能详细描述>
- *
- * @param in
- * @return
- * @see [类、类#方法、类#成员]
- */
- public static String Inputstr2Str_ByteArrayOutputStream(InputStream in,String encode)
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int len = 0;
- try
- {
- if (encode == null || encode.equals(""))
- {
- // 默认以utf-8形式
- encode = "utf-8";
- }
- while ((len = in.read(b)) > 0)
- {
- out.write(b, 0, len);
- }
- return out.toString(encode);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return "";
- }
- /**
- * 利用ByteArrayInputStream:String------------------>InputStream <功能详细描述>
- *
- * @param inStr
- * @return
- * @see [类、类#方法、类#成员]
- */
- public static InputStream Str2Inputstr(String inStr)
- {
- try
- {
- // return new ByteArrayInputStream(inStr.getBytes());
- // return new ByteArrayInputStream(inStr.getBytes("UTF-8"));
- return new StringBufferInputStream(inStr);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- return null;
- }
=====================================
从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)报错问题。
Java 里把 InputStream 转换成 String 的几种方法的更多相关文章
- Java 把 InputStream 转换成 String 的几种方法
我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量. 未真正关注这个问题之 ...
- DataTable 转换成 Json的3种方法
在web开发中,我们可能会有这样的需求,为了便于前台的JS的处理,我们需要将查询出的数据源格式比如:List<T>.DataTable转换为Json格式.特别在使用Extjs框架的时候,A ...
- JavaScript进阶(四)js字符串转换成数字的三种方法
js字符串转换成数字的三种方法 在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b. ...
- 用jquery解析JSON数据的方法以及字符串转换成json的3种方法
用jquery解析JSON数据的方法,作为jquery异步请求的传输对象,jquery请求后返回的结果是 json对象,这里考虑的都是服务器返回JSON形式的字符串的形式,对于利用JSONObject ...
- js 字符串转换成数字的三种方法
在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形 ...
- JavaScript字符串转换成数字的三种方法
在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形 ...
- python将字符串转换成字典的几种方法
当我们遇到类似于{‘a’:1, 'b':2, 'c':3}这种字符串时,想要把它转换成字典进行处理,可以使用以下几种方法: 1. Python自带的eval函数(不安全) dictstr = '{&q ...
- python字符串转换成变量的几种方法
个人比较喜欢用第三种方法 var = "This is a string" varName = 'var' s= locals()[varName] s2=vars()[varNa ...
- map转换成JSON的3种方法
http://www.json.cn/JSON格式校验 1 json-lib <dependency> <groupId>net.sf.json-lib</groupId ...
随机推荐
- Raspberry pi raspbain系统下使用vim
一开始 apt-get install vim不好用. 在putty中执行这条命令就可以了. sudo apt-get update && sudo apt-get install v ...
- hdu 4714 Tree2cycle dp
用树形dp做的,dp[t][i]表示t及其孩子入度都已经小于等于2并且t这个节点的入度等于i的最优解. 那么转移什么的自己想想就能明白了. 关键在于这个题目会暴栈,所以我用了一次bfs搜索出节点的顺序 ...
- hdoj 2066 一个人的旅行 【多源多汇最短路】
题目:hdoj 2066 一个人的旅行 方法:缩点 + 最短路 分析:看了大神的一篇博客,讲冗余压缩的,然后就想找一个多源最短路练练手. 这个题目就是典型的多源多汇最短路 方法:把全部的源点压缩成一个 ...
- Swift - 给项目导入资源
如果想添加资源到项目中去,只要通过鼠标左键将文件或者存有文件的文件夹直接拖到Xcode中. 当松开鼠标后会弹出如下面板: (1)勾上“Copy items if needed”就会拷贝文件进项目, ...
- java学习之路----内存的分析
java内存分析 在java中,java语言对程序员做了一个美好的承诺,就是程序员无需去管理内存,因为有GC,其实不然; 1.垃圾回收并不 ...
- gcc manual
$ gcc --helpUsage: gcc [options] file...Options: -pass-exit-codes Exit with highest error c ...
- hdu 5183(hash)
传送门:Negative and Positive (NP) 题意:给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP− ...
- 11gR2(11.2) RAC TAF Configuration for Admin and Policy Managed Databases (文档 ID 1312749.1)
In this Document Purpose _afrLoop=1459323732561579&id=1312749.1&displayIndex=10&_afr ...
- Ajax 下拉列表联动显示
一般处理程序文件 代码 using System;using System.Web;using System.Linq;using System.Data.Linq;using System.Text ...
- Xamarin 安装教程 支持Visual Studio 2013
本文的前提是你已经正确的安装了VS 2013. 本文的全部步骤在Win7 Ultimate 64系统上測试通过.支持VS 2013,我用的版本号是VS 2013 update2. 安装 1. ...