Java输入流编码格式_java获得stream流或文件的编码格式

需求

直接上代码

String url = "http://xxx.xxx/xx.txt"; //需要从网络读取的文件

Inputstream is = new URL(url).openStream;

//接下来,把Inputstream读成String

然而该stream的编码未知,且不同文件编码不同。默认使用utf-8或gb2312都会造成部分结果乱码。

solution

//BufferedInputStream支持mark,可以重复读取stream,避免网络请求2次

BufferedInputStream is = new BufferedInputStream(new URL(url).openStream());

is.mark(1000000);//10M

//第一次处理stream,得到encoding

String encoding = new TikaEncodingDetector().guessEncoding(is);

is.reset();

return IOUtils.toString(is, encoding);

解释

背景知识

心路历程

首先尝试stream或file有没有方法直接getEncoding,得到结论:

You cannot determine the encoding of a arbitrary byte stream. 如果理解了字符编码背景知识,这个应该很容易理解参考

那么如何得到一个流的编码,还是有人做出了工具:

org.apache.any23

apache-any23-encoding

1.1

public static Charset guessCharset(InputStream is) throws IOException {

return Charset.forName(new TikaEncodingDetector().guessEncoding(is));

}

guessEncoding函数名很灵性。原理是读一遍流,根据各种编码特点推断输入流的编码。既然是guess就不是100%准的,不过实用效果不错。感兴趣的同学可以深入一下。

guessEncoding已经把stream读过一遍了,直接转string得到空字符串。又不想再发一次网络请求重新获取。然后,发现BufferedInputStream支持mark/reset, 重复读取。finished,完美。

参考:http://zhangbo-peipei-163-com.iteye.com/blog/2022460

副产品:IO流的关闭问题

FIleInputStream的finalize方法会调用close(),即gc时会帮你关闭io,but,并不建议这样做。理由:

资源没有被及时释放;

finalize方法调用导致gc时间过长

it is not a good idea to rely on it because it runs unpredictably. 参考1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值