下载网页发现HttpURLConnection返回的InputStream不支持mark,reset的情况下,如何实现这个inputstream的多次使用

morocco 2008-01-18 05:18:06
因为为了保证文件没有乱码,所以读的时候需要用到

java.io.BufferedReader l_reader = new java.io.BufferedReader(
new java.io.InputStreamReader(urlstream,这里填入编码));


而为了得到编码,要先分析一次数据,分析了那个流就算使用过了,难道要下两次链接吗,或者说把这个流对象序列化保存到硬盘上然后再读取一个拷贝(因为InputStream没有实现Clone)。

再次申明,这个InputStream是不支持reset和mark的

尝试过用ByteArrayInputStream来曲线保存这个输入流,但是最后会发现数据被改变过了,有些地方出现了乱码。所以不行。


于是想问问大家,除了下载两次网页和序列化输出外,还有没有其他办法可以读两次这个流。
...全文
1022 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
老紫竹 2008-01-20
  • 打赏
  • 举报
回复
你那个累死了!

byte[] bs= new byte[1024]; // 至少用1K的缓冲吧
int len = -1;
while((len=is.read(bs))!=-1){
bos.write(bs,0,len);
}
morocco 2008-01-20
  • 打赏
  • 举报
回复
自己写了个方法把inputstream转成BYTE[],好像资源占用还可以接受
public static byte[] InputStreamToByte(InputStream is) throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch;
while ((ch = is.read()) != -1)
{
bos.write(ch);
}
byte b[]=bos.toByteArray();
bos.close();
return b;
}
morocco 2008-01-20
  • 打赏
  • 举报
回复
谢谢大家,我搞定了,原来我以前的BYTE[]的来源是把已经解出是乱码的String类直接String.getBytes()的,现在直接从STREAM里得到BYTE就可以了,我犯低级错误了
老紫竹 2008-01-20
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20080110/19/7cb462f1-cac6-4c28-848e-0a879f4fd642.html
morocco 2008-01-20
  • 打赏
  • 举报
回复
谢谢java2000_net老大,
回楼上的,我正在研究怎么给分........点哪里啊,我记得以前有个给分按钮,最近几次我都找不到了
vlinux 2008-01-20
  • 打赏
  • 举报
回复
你说这样的程序一个变量得占多少内存?(我觉得怎么着也得1K吧?)1K内存?那是变量名!4K起。你别大,还不压缩。你得研究程序员的编程心理,愿意new 1K内存作变量名的程序员,根本不在乎再多掏3K。什么叫MVP,你知道吗?MVP就是写什么程序,都写最长的,不写最好的!所以,我们做程序的口号就是:不求最好,但求最长!

PS,现在的人都不流行给分了...还是以前的CSDN好啊
sunyujia 2008-01-19
  • 打赏
  • 举报
回复
处理btye不当是会乱码的不是sun的bug是楼主的程序有bug
vlinux 2008-01-19
  • 打赏
  • 举报
回复
是么,我觉得SUN不会犯这么严重的错误吧
你用url.openStream或者直接用Socket抓页面下来看看
我写了一个url.openStream的,用来抓csdn的主页,然后再转换成utf-8没有任何问题
sunyujia 2008-01-19
  • 打赏
  • 举报
回复
cpu占用也很高呵呵,这段程序个人用途,以前用来检查是否有出售最新二手火车票的
sunyujia 2008-01-19
  • 打赏
  • 举报
回复
没看明白你的需求发段代码吧,没乱码我测过以前写的,要求内存占用比较高
/**
* 刷新URL链接
*
* @throws Throwable
*
*/
public String refreshURL() throws Throwable {
InputStream in = null;
byte[] buff = new byte[buffSize];
List<Byte> byteList = new ArrayList<Byte>();
URL theURL = new URL(this.url);
URLConnection urlConnection = theURL.openConnection();
urlConnection.connect();
in = urlConnection.getInputStream();
int i = 0;
while ((i = in.read(buff)) != -1) {
for (int k = 0; k < i; k++) {
byteList.add(new Byte(buff[k]));
}
}
in.close();
byte[] content = new byte[byteList.size()];
for (int j = 0, size = byteList.size(); j < size; j++) {
content[j] = byteList.get(j).byteValue();
}
String ret = new String(content);
ret = ret.substring(ret.indexOf("item"));
return ret;
}
morocco 2008-01-19
  • 打赏
  • 举报
回复
我Byte[]出来的结果也会有少量乱码,我测试过的,本来我就是用的这个,以为可以,后来无意中发现出现了乱码,仔细一看,还不少,星星点点四处分布。


比如你试试吧这个页面用先转化为BYTE,然后再用变回流,就会发现解出来有少量乱码,就跟new String(s.getByte(),"utf-8")的结果一样
vlinux 2008-01-19
  • 打赏
  • 举报
回复
尝试过用ByteArrayInputStream来曲线保存这个输入流,但是最后会发现数据被改变过了,有些地方出现了乱码。所以不行。
--------------------------------
我记得我是成功的啊
老紫竹 2008-01-19
  • 打赏
  • 举报
回复
文件不大,你何必保存输入流副本? 你直接读取文件数据到内存就行了!

直接操作byte[] 比操作 InputStream 不是更方便吗!?
morocco 2008-01-19
  • 打赏
  • 举报
回复
如果你下载的文件不是很大,比如小于10M, 你服务器的内存也很大,你的并发用户不是非常大

你可以考虑将文件一次性读取到内存就可以了!

如果太大,只能用临时文件解决了,否则内存会溢出!



我好像没有理解你的意思....我就是问有没有办法在内存里保存两个输入流的对象副本
euroman 2008-01-19
  • 打赏
  • 举报
回复
save it to a temperarory file ok?
老紫竹 2008-01-19
  • 打赏
  • 举报
回复
如果你下载的文件不是很大,比如小于10M, 你服务器的内存也很大,你的并发用户不是非常大

你可以考虑将文件一次性读取到内存就可以了!

如果太大,只能用临时文件解决了,否则内存会溢出!
vlinux 2008-01-19
  • 打赏
  • 举报
回复
我也那么觉得,因为我的网络爬虫也是保存byte[]的,没遇到任何问题
morocco 2008-01-18
  • 打赏
  • 举报
回复
HttpURLConnection .getContentType();
基本上是很难拿到这个编码的,基本上都是空的.

至于第二个方法,我需要的是绝对保险的方式,还有就是我需要的是完整的网页代码,包括前面的东西,因此也不行啊
老紫竹 2008-01-18
  • 打赏
  • 举报
回复
还有
HttpURLConnection.getContentEncoding()


另外,如果是网页的话,最前面几行基本都有contentType的标签,也可以解析得到。


所以,可以考虑不要全部读取,只读取最前面的1-2K字节放数组里用来解析,获得编码后,这个数组可以被再次使用。
老紫竹 2008-01-18
  • 打赏
  • 举报
回复
我给你个建议

HttpURLConnection 有个方法你可能用得到
HttpURLConnection .getContentType();
从这里面你能解析到编码方式的

text/html; charset=gb2312


加载更多回复(1)

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧