2 sinat 33645256 sinat_33645256 于 2016.02.12 20:34 提问

关于Java中FileInputStream类的一些新手疑问

在每次使用FileInputStream的read方法时,需要用到字节数组bytes和真实读取长度len,如代码:

 public static void read(){
        File file = new File("D:/学习/Android/代码/Workplace/Java_8_1_File/a.txt");
        try {
            //针对文件创建一个输入流
            InputStream in = new FileInputStream(file);
            byte[] bytes = new byte[1024*1024*10];//定义一个10MB的字节数组
            int len = -1;//每次真实读取的长度
            StringBuffer buf = new StringBuffer();

            try {
                while((len = in.read(bytes))!=-1){
                    buf.append(new String(bytes,0,len));
                }
                in.close();//关闭
                System.out.println(buf);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

,其中在循环里,buf.append那一句中,每一次都把0处len字节数加入到buf中,那么倘若文件的数据是:
01234
为何最后输出的结果不是:
001012012301234
呢?

2个回答

fk002008
fk002008   2016.02.12 21:43
已采纳

首先呢这个bytes是干什么的?
缓冲区,就是防止大数据量的时候,我们每次只读取一部分数据到缓冲区中进行操作
那么这个len又是什么呢?
它是实际的读取字节的数

你如果学过数据结构就知道这是一种线性表的思想
因为有时候读取的数据是不能填满这个bytes的,那么len就是实际的数

你抓住读取思想:
每次都是读取文件的bytes大小数据放到bytes数组中
所以取的时候自然是从bytes的0处去取
buf.append(new String(bytes,0,len));
加上len,用于防止最后一次的操作错误,最后一次取的数据实际长度是小于等于bytes的长度的,如果小于,那么bytes还残留着上次的数据。
所以使用len来读取最后一次实际取的数据。

建议去看看线性表

sinat_33645256
sinat_33645256 谢谢,我明白了,不过还没有学数据结构,我会去看一看的。
2 年多之前 回复
fk002008
fk002008 如果按照你的理解第一次bytes是ab,第二次bytes是abcd,依次下去这个bytes失去了缓冲的意义,建议你还是看看线性表,此处的bytes就是限制每次读文件的量,这样一个大文件可以分几次之后放入内存中处理,每次读取都是从头到尾填满整个bytes,如果填不满这个len就发挥作用了
2 年多之前 回复
fk002008
fk002008 然后第二次读文件那就是cd了,也就是说数组此时的东西是cd了,可不是把文件的东西追加到之前的ab的后面,所以还要从0开始截取bytes的数据
2 年多之前 回复
fk002008
fk002008 回复lambda-fk: 假设你bytes数组每次只能读取2个,len就是2,那么循环第一次读取的是ab,然后从bytes中0开始读取2个,
2 年多之前 回复
fk002008
fk002008 回复sweetstar86: 注意你读取文件的时候使用的是bytes,是按照数组容量来读取文件的,len是实际的读取个数,你现在把读文件和那个存入数组的操作弄混了
2 年多之前 回复
sinat_33645256
sinat_33645256 我的理解是,比如abcde这些数据,然后循环第一次截取了ab,第二次的时候,还是0处开始,那不会是ababcd吗
2 年多之前 回复
fk002008
fk002008 你把你文件的数据弄的大一些,或者你把缓冲区数组的长度调的小一点,能有3次以上的循环你就明白了
2 年多之前 回复
fk002008
fk002008 回复sweetstar86: 注意你是在循环中处理的,append从0开始buf.append(new String(bytes,0,len));那是指从数组的第0位开始截取len个元素,怎么会重复呢?
2 年多之前 回复
sinat_33645256
sinat_33645256 而且如果循环继续的话,那append每次从0开始不是会造成相同数据的叠加读出吗?
2 年多之前 回复
sinat_33645256
sinat_33645256 我试着把循环去掉之后,结果不出错也相同,这是为什么?观察debug也只是运行了一次循环。。。
2 年多之前 回复
caozhy
caozhy   Ds   Rxr 2016.02.12 21:50

一个是字符串,一个是字节数组,既然你是文本文件,就不应该用FileInputStream去读。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
关于拼多多新手开店的疑问及解答
    新手在拼多多开店肯定会遇到不少问题,例如开车商品的曝光问题、系统推荐一样的竞品怎么办、活动定价低却不通过等,这些都是会影响拼多多店铺运营的。就这几点疑惑,为大家整理了4个疑问及解答。    1、为什么我两个店同样的商品开场景推广,一个店只开的商品只有几个曝光率就有几千个,另一个店开了十几个,曝光率只有几十呢?    商品基础一样吗?基础销量、有效评价和自然排名一样吗?如果不一样的话,那么在...
java的输入字节流 FileInputStream类
File类: 用于描述一个文件或者文件夹的。  通过File对象我们可以读取文件或者文件夹的属性数据,如果我们需要读取文件的内容数据,那么我们需要使用IO流技术。   IO流(Input Output) IO流分类: 如果是按照数据的流向划分: 输入流 输出流 如果按照处理的单位划分: 字节流: 字节流读取得都是文件中二进制数据,读取到二进制数据不会经过任何的
用FileInputStream和FileOutputStream拷贝文件
在E:\JavaIO中新建abc.txt文件,并在里面写上一些文字。现在要做的是,在Eclipse里面用FileInputStream和 FileOutputStream的read()和write()方法,实现,abc.txt文件的拷贝新建IOUitl.java,代码如下: import java.io.File; import java.io.FileInputStream; impor
Java中FileInputStream,FileReader等的区别
1. File类  1)File类介绍 File类封装了对用户机器的文件系统进行操作的功能。例如,可以用File类获得文件上次修改的时间移动,或者对文件进行删除、重命名。换句话说,流类关注的是文件内容,而File类关注的是文件在磁盘上的存储。  File类的主要方法有:getName(),getCanonicalFile(),lastModified(),isDerector(),isFil
java中讲讲FileInputStream的用法,举例?
FileInputStream是InputStream的继承类,从字面上就可看出,它的主要功能就是能从磁盘上读入文件。read方法会一个一个字节的从磁盘往回读数据。 例:2.2.1 import java.io.*; public class TestMark_to_win {     public static void main(String args[]) throws Exce
java中FileInputStream与InputStream的available()方法的作用
available()方法 如果要从网络中下载文件时,我们知道网络是不稳定的,也就是说网络下载时,read()方法是阻塞的,说明这时我们用inputStream.available()获取不到文件的总大小。 此时就需要通过 HttpURLConnection httpconn = (HttpURLConnection)url.openConnection(); httpconn.g
java中FileOutputStream和FileInputStream类用法
I/O类包括节点流类和包装流类 FileOutputStream和FileInputStream创建磁盘文件的输入输出流对象 创建FileInputStream实例对象时,指定的文件应当是存在和可读的,创建FileOutputStream实例对象时,如果指定的文件已经存在,这个文件中的原来内容将被清除 创建FileOutputStream实例对象时,可以指定还不存在的文件名,不能指定一个已被
file,fileInputStream, fileReader,inputStreamReader等java文件流类的关系区别
1. File类  1)File类介绍 File类封装了对用户机器的文件系统进行操作的功能。例如,可以用File类获得文件上次修改的时间移动,或者对文件进行删除、重命名。换句话说,流类关注的是文件内容,而File类关注的是文件在磁盘上的存储。  File类的主要方法有:getName(),getCanonicalFile(),lastModified(),isDerector(),isFil
Java的IO操作(一) - File类,RandomAccessFile类,FileInputStream、FileOutputStream类
在Java中,所有的输入、输出问题都会被抽象成流(Stream)对象来解决。下面介绍一下常用的输入、输出流对象的使用方法。 1、 File类 File类是文件的抽象代表。一个文件(包括目录)就是一个File类的实例。java.io.File类为我们提供了一个抽象的、系统独立的文件表示,我们不必纠结于因为不同的操作系统文件路径的表示方法不同而造成的差异,File会将传进去的路径自动转换为
InputStream read()方法详解
在Java7中,InputStream被定义为一个抽象类,相应的,该类下的read()方法也是一个抽象方法,这也就意味着必须有一个类继承InputStream并且实现这个read方法。 查阅Java7 API,我们可以看到,在InputStream中定义了三个重载的read()方法: 但是在这三个方法中,只有参数列表为空的read方法定义为抽象方法,这也就意味着在直接继承自InputStre