InputStream的read()方法
InputStream 此抽象类是表示字节输入流的所有类的超类。
我们从输入流中读取数据最常用的方法基本上就是如下3个read()方法了:
1、 read()方法,这个方法从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
2、read(byte[] b,int off,int len)方法,将输入流中最多 len 个数据字节读入 byte 数组。尝试读取len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。
3、read(byte[] b)方法,从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。
第一个方法典型的确定就是处理效率低,不是某些特殊情况,很少使用它,下面说说第2个方法跟第3个方法,第3个方法的本本质其实就是第2个方法的特殊情况,效果等同于:
read(b, 0,b.length)
所以这里把他们放着一起讨论。
从第2个方法的API文档说明来看:“将输入流中最多len 个数据字节读入 byte 数组。尝试读取len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。”,最多读取len个字节,这究竟是何意?API文档并没有详细说明。是不是就意味着有可能(注意这里是有可能而不是一定,)读取不到len个字节呢?答案是“是的”。虽然造成这种情况的原因是什么个人并不知道,但是我们可以通过例子来发现这种情况,下面是源代码(由于只是简单的示例,所以代码也就随便写了):
ServerSocket端:
java代码:
package myspider; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * * @author mark */ public class MyServerSocket { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8888); System.out.println("runing"); while (true) { byte[] b = new byte[22480]; int readBytes = 0; Socket s = ss.accept(); InputStream is = s.getInputStream(); while (readBytes < 22480) { int read = is.read(b, readBytes, 22480 - readBytes); System.out.println(read); if (read == -1) { break; } readBytes += read; } File f = new File("F:\\project\\bocln_nacec\\xml\\ey.xml"); if (!f.exists()) { f.createNewFile(); System.out.println("creat " + f.toString()); } FileOutputStream fos = new FileOutputStream(f); fos.write(b, 0, readBytes); fos.flush(); fos.close(); System.out.println("complete"); is.close(); s.close(); } } }
Socket端:
package myspider; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * * @author mark */ public class MySocket { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1", 8888); OutputStream os = s.getOutputStream(); File f = new File("F:\\project\\bocln_nacec\\xml\\ye.xml"); InputStream is = new FileInputStream(f); byte[] b = new byte[22480]; int i = is.read(b); is.close(); os.write(b, 0, i); os.flush(); os.close(); s.close(); } }
先运行MyServerSocket,让后多次运行MySocket,这是控制台的输出结果(ye.xml文件长度为20389):
java代码:
runing 20389 -1 creat F:\project\bocln_nacec\xml\ey.xml complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 8760 11629 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 3760 620 16009 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 8760 11629 -1 complete 20389 -1 complete 20389 -1 complete 8760 11629 -1 complete 20389 -1 complete 20389 -1 complete 8760 11629 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete 20389 -1 complete
通过观察发现,在大多数情况下,我们能够用is.read(b, readBytes, 22480 - readBytes)一次性就读完整个文件,但是还是有极少数情况,我们需要两次(如36、37两行)甚至两次以上(如58、59、60)调用is.read(b, readBytes, 22480 - readBytes)方法才能把整个文件读取完。这里由于文件最长只有20389,所以我们能读到的最大字节数也就是20389而不会是22480了。
那么我们怎样写代码才能保证在数据流没有到达末尾的情况下读取到自己想要的长度的字节数据呢?我们可以这样写:
java代码:
int readBytes=0; Byte[] b=new byte[1024]//1024可改成任何需要的值 int len=b.length; while (readBytes < len) { int read = is.read(b, readBytes, len - readBytes); //判断是不是读到了数据流的末尾 ,防止出现死循环。 if (read == -1) { break; } readBytes += read; }
InputStream的read()方法相关推荐
- [五] JavaIO之InputStream OutputStream简介 方法列表说明
InputStream 和 OutputStream 对于字节流的输入和输出 是作为协议的存在 所以有必要了解下这两个类提供出来的基本约定 这两个类是抽象类,而且基本上没什么实现,都是依赖于子类具体的 ...
- transferto的流这么关闭_Java 9中InputStream的transferTo()方法的重要性?
在Java 9中,transferTo()方法已添加到InputStream类中.该方法已用于在Java中将数据从输入流复制到输出流.这意味着它将从输入流中读取所有字节,然后按读取顺序将字节写入输出流 ...
- InputStream的read方法
InputStream此抽象类是表示字节输入流的所有类的超类. 我们从输入流中读取数据最常用的方法基本上就是如下3个read()方法了: 1. read()方法,这个方法从输入流中读取数据的下一个字节 ...
- Java:浅谈InputStream的close方法
原则:最好在任何时候使用InputStream或者OutputStream的时候,在finally中调用close()方法,显式关闭. 一个典型的示例 InputStream in = null; t ...
- java关闭inputstream_Java:浅谈InputStream的close方法
原则:最好在任何时候使用InputStream或者OutputStream的时候,在finally中调用close()方法,显式关闭. 一个典型的示例 InputStream in = null; t ...
- InputStream中通过mark和reset方法重复利用缓存
通过缓存InputStream可重复利用一个InputStream,但是要缓存一整个InputStream内存压力可能是比较大的.如果第一次读取InputStream是用来判断文件流类型,文件编码等用 ...
- inputstream示例_Java InputStream close()方法与示例
inputstream示例 InputStream类close()方法 (InputStream Class close() method) close() method is available i ...
- java input.close()_Java InputStream close()方法与示例
InputStream类close()方法close()方法在java.io包中可用. close()方法用于关闭此InputStream并释放与此流链接的所有系统资源. close()方法是一种非静 ...
- java中transferto,Java 9新增的有趣方法InputStream.transferTo()
Java 9新增的有趣方法InputStream.transferTo() 2018.2.1 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. JDK 9新增了一个有趣的方法,Inpu ...
最新文章
- 电子商务中遇到组合搜索的问题
- Apache Flink 零基础入门(七)Flink中keyBy三种方式指定key
- flask-session总结
- java里shake是什么意思_shake是什么意思_shake在线翻译_英语_读音_用法_例句_海词词典...
- 《庆余年》里的五竹,到底是不是机器人?
- [转载] 【Python】不用numpy用纯python求极差、平均数、中位数、众数与方差,python的打印到控制台
- 如何在 macOS 中将用户帐户拆分为两个单独的帐户?
- PhpStorm之三种视图模式
- java去掉边框_java swing怎么去掉边框
- 计算机更改刷新频率,电脑屏幕刷新率怎么调节?怎么更改电脑屏幕刷新率?
- 卡刷android版本不一致,你好,请问一下,关于跨安卓版本刷机的问题
- 项目集管理PgMP:聚焦战略、收益与治理︱项目管理者联盟联合创始人宣晓锋
- 计算机显示器工作的原理,液晶显示器的工作原理
- 用正则表达式提取富文本内容(去除html,p,a等标签)
- html实现用户调查的表单网页,江苏开放大学网页制作基础及HTML测试作业二制作1个E游调查的表单网页...
- 【2022最新Java面试宝典】—— Java虚拟机(JVM)面试题(51道含答案)
- 支付宝 自动发货 php,ecshop 支付宝自动发货接口
- centos8安装nfs服务器
- html css 八卦图,CSS动画-八卦图
- python动态爱心曲线_用Python来画一条动态心形曲线