InputStream为什么不能被重复读取?

2024-02-16 00:08

本文主要是介绍InputStream为什么不能被重复读取?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,熟悉Java的人可能都知道,Java中的Inputstream是不能重复读取的。 
但是有没有想过,InputStream为什么不能重复读呢? 
其实要回答“为什么”这个问题很简单,就是人家接口就是这么设计的,不能重复读。 
所以今天要讨论的问题更像是:Java的InputStream为什么要设计为不能重复读? 
关于InputStream为什么不能重复读取,网上也各有说法: 
有的同学说: 
“InputStream就类比成一个杯子,杯子里的水就像InputStream里的数据,你把杯子里的水拿出来了,杯子的水就没有了,InputStream也是同样的道理。” 
比喻的非常好,让我们从直观上认识了InputStream为什么不能重复被读。 
也有的同学从更深的代码角度去分析: 
“在InputStream读取的时候,会有一个pos指针,他指示每次读取之后下一次要读取的起始位置,当读到最后一个字符的时候,pos指针不会重置。” 
说的也有道理,就是说InputStream的读取是单向的。但是并不是所有的InputStream实现类都是这样的实现方式。

Java代码   收藏代码
  1. //BufferedInputStream代码片段:  
  2.  public synchronized int read() throws IOException {  
  3.         if (pos >= count) {  
  4.             fill();  
  5.             if (pos >= count)  
  6.                 return -1;  
  7.         }  
  8.         return getBufIfOpen()[pos++] & 0xff;  
  9.     }  
  10.   
  11. //FileInputStream代码片段:  
  12. public native int read() throws IOException;  




我们知道: 
Java 的List内部是使用数组实现的,遍历的时候也有一个pos指针。但是没有说List遍历一个第二次遍历就没有了。第二次遍历是创建新的Iterator,所以pos也回到了数组起始位置。对于某些InputStream当然可以也这么做。例如:ByteArrayInputStream 
ByteArrayInputStream就是将一个Java的byte数组保存到对象里,然后读取的时候遍历该byte数组。 

Java代码   收藏代码
  1. public ByteArrayInputStream(byte buf[]) {  
  2.         this.buf = buf;  
  3.         this.pos = 0;  
  4.         this.count = buf.length;  
  5. }  
  6.   
  7. public synchronized int read() {  
  8.         return (pos < count) ? (buf[pos++] & 0xff) : -1;  
  9. }  


就ByteArrayInputStream而言,要实现重复读取是很简单的,但是为什么没有。我想是为了遵循InputStream的统一标准。 
在InputStream的read方法的注释上明确说明: 

Java代码   收藏代码
  1. /** 
  2.      * Reads the next byte of data from the input stream. The value byte is 
  3.      * returned as an <code>int</code> in the range <code>0</code> to 
  4.      * <code>255</code>. If no byte is available because the end of the stream 
  5.      * has been reached, the value <code>-1</code> is returned. This method 
  6.      * blocks until input data is available, the end of the stream is detected, 
  7.      * or an exception is thrown. 
  8.      * 
  9.      * <p> A subclass must provide an implementation of this method. 
  10.      * 
  11.      * @return     the next byte of data, or <code>-1</code> if the end of the 
  12.      *             stream is reached. 
  13.      * @exception  IOException  if an I/O error occurs. 
  14.      */  
  15.     public abstract int read() throws IOException;  


当流到达末尾后,返回-1. 

其实像FileInputStream这样的文件流,要实现重复使用可能也并不是很难,利用缓存什么的应该能做到(大文件读取就悲剧了,呵呵呵)。 
但是InputStream顾名思义就是一个单向的字节流,跟水流一样,要想再次使用就自己再去源头取一下。 
InputStream其实不像杯子,更像是一根水管,要想喝水了,就在把水管架在水源与杯子之间,让水流到杯子里(注意:这个动作完成了之后水管里面就没有水了)。 
这样看来,InputStream其实是一个数据通道,只负责数据的流通,并不负责数据的处理和存储等其他工作范畴。 
前面讲过,其实有的InputStream实现类是可以实现数据的处理工作的。但是没有这么做,这就是规范和标准的重要性。 

这篇关于InputStream为什么不能被重复读取?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/712944

相关文章

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Redis 多规则限流和防重复提交方案实现小结

《Redis多规则限流和防重复提交方案实现小结》本文主要介绍了Redis多规则限流和防重复提交方案实现小结,包括使用String结构和Zset结构来记录用户IP的访问次数,具有一定的参考价值,感兴趣... 目录一:使用 String 结构记录固定时间段内某用户 IP 访问某接口的次数二:使用 Zset 进行

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl