关于Stream的读写

public abstract int Read(byte[] buffer, int offset, int count)

  • buffer: 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。
  • offsetbuffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。
  • count: 要从当前流中最多读取的字节数。

返回值读入缓冲区中的总字节数。如果当前可用的字节数没有请求的字节数那么多,则总字节数可能小于请求的字节数,或者如果已到达流的末尾,则为零 (0)。此方法的实现从当前流中读取最多的 count 个字节,并将它们存储在从 offset 开始的 buffer 中。流中的当前位置提升已读取的字节数;

  • FileStream stream=new FileStream(url,FileMode.Open);
  • stream.Seek(offset,SeekOrigin.Begin);//本句相当于stream.position=offset;//stream的position默认是0,读一次后position会对应加到读的位置。
  • //每次读之前最好都先设置一下流的读取位置。SeekOrigin.Begin表示从0开始偏移offset个数开始读,还有SeekOrigin.End和Current表示从结尾和当前位置开始偏移offset个数指定给Position。
  • int ret =stream.Read(data,offset,count);//这里的offset是data数组的偏移和大小,
  • stream.Close();//本句必须要加 不要忘记

    //代码意思是从流偏移量为offset的地方开始读,一共读count个字节,存在data数组的offset偏移处,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。


用这个方法读保证读完,因为streamingasset和网络流目录可能一次性读不完
byte[] b = new byte[count];
  int readCount = 0; // 已经成功读取的字节的个数
  while (readCount < count) {
   readCount += in.read(bytes, readCount, count - readCount);
  }

-------------------------------------------------------------------------------------------

Stream.Write(byte[] buffer, int offset, int count)

  • FileStream stream= new FileStream(url,FileMode.Create);
  • if(stream!=null){
  • stream.position=0;
  • stream.write(data,offset,count);//从stream的0开始写入 一共写count字节。data从offset开始写到stream。
  • stream.Flush();//如果暂时不close  默认是暂时不写数据的,那么flush是立刻写入数据。
  • stream.Close();//关闭后 也是立刻写入数据。
  • }
  • ------------------------------------------------------------------序列化-------------------------------------------------------------------
    • FileStream stream= new FileStream(url,FileMode.Create);
  • sdFormater.Write(stream,(int)1);//int
    • sdFormater.Write(stream,"name");//string
    • stream.close();
    //read:
  • sdBinaryReader stream=new sdBinaryReader(data,length);//test
  • int a;string b;
  • sdFormater.Read(stream,ref a);//a=1
    • sdFormater.Read(stream,ref b);//b="name"
    • //只要满足读取和写入的顺序完全一样,数据的序列化和反序列就可以完成,因为每次读取和写入的数据类型所占的字节数是固定的。比如byte1个字节,int占4个字节。
    • //另外文件的读写分2种,一种是整个数据结构的读写 比如一个大的string 写到byte文件文件里,那么读出来直接转换string就可以获取到数据;另外一种就是上边的 多个数据写到一个文件里边,那么读取也要按照分部读取再来转换(string)类型。直接转换肯定是错误的,读取顺序乱了 也是错误的。

------------------------------------------------------------------------------------



java InputStream读取数据问题

1. 关于InputStream.read()
     在从数据流里读取数据时,为图简单,经常用InputStream.read()方法。这个方法是从流里每次只读取读取一个字节,效率会非常低。     更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次读取多个字节。


2. 关于InputStream类的available()方法
    要一次读取多个字节时,经常用到InputStream.available()方法,这个方法可以在读写操作前先得知数据流里有多少个字节可以读取。需要注意的是,如果这个方法用在从本
地文件读取数据时,一般不会遇到问题,但如果是用于网络操作,就经常会遇到一些麻烦。比如,Socket通讯时,对方明明发来了1000个字节,但是自己的程序调用available()方法却只得到900,或者100,甚至是0,感觉有点莫名其妙,怎么也找不到原因。其实,这是因为网络通讯往往是间断性的,一串字节往往分几批进行发送。本地程序调用available()方法有时得到0,这可能是对方还没有响应,也可能是对方已经响应了,但是数据还没有送达本地。对方发送了1000个字节给你,也许分成3批到达,这你就要调用3次available()方法才能将数据总数全部得到。
      如果这样写代码:
  int count = in.available();
  byte[] b = new byte[count];
  in.read(b);
      在进行网络操作时往往出错,因为你调用available()方法时,对发发送的数据可能还没有到达,你得到的count是0。
         需要改成这样:
  int count = 0;
  while (count == 0) {
   count = in.available();
  }
  byte[] b = new byte[count];
  in.read(b);
3. 关于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常 读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅读Java的API说明就发现了,这个方法 并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。因此,如果要让程序读取count个字节,最好用以下代码:

  InputStream in = getResources().getAssets().open(fileName);   
  byte[] b = new byte[count];
  int readCount = 0; // 已经成功读取的字节的个数
  while (readCount < count) {
   readCount += in.read(bytes, readCount, count - readCount);
  }
      用这段代码可以保证读取count个字节,除非中途遇到IO异常或者到了数据流的结尾(EOFException)

4.关于3的在while里边读取数据 循环很多次 还是读不出来的时候  一般说明 已经读到流的尾处了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值