android

Java.IO.InputStream.skip() 错误(跳过字节数和预想的不等)

位置:首页 > android > 开发技巧,2013-05-26
最近写一个网络下载软件,需要使用Java.IO.InputStream.skip(longn)方法,它的作用是从输入流中跳过n个字节,比如inputStream.skip(12),就是从inputSt...

最近写一个网络下载软件,需要使用Java.IO.InputStream.skip(long n) 方法,它的作用从输入流中跳过 n 个字节,比如 inputStream.skip(12),

就是从inputStream中读最近写一个网络下载软件,需要使用取数据流时,跳过前 12 个字节,从第13个字节读取,方法的返回值就是实际跳过的字

Java.IO.InputStream.skip(long n) 方法,节数,按道理返回值应该等于输入的参数 n (the actual number of bytes skipped.),但是它的我使

的时候,返回值往往小于 n,出错!

       Java 官方文档指出这个问题,建议自己去写一个方法来实现这个功能(Subclasses are  encouraged to provide a more efficient

 implementation of this method. For instance, the implementation may depend on the ability to seek),似乎说这个方法能否成功,

也要取 决于机器的能力。 

       其实,如果自己写一个方法,思路就是从头开始读取,等到读到 n 时,再使用,这恰恰就是Java 源码中 InputStream.skip 的思路,一下是自己
写的一个方法

  1. /*重写了Inpustream 中的skip(long n) 方法,将数据流中起始的n 个字节跳过*/  
  2.  private long skipBytesFromStream(InputStream inputStream, long n) {  
  3.   long remaining = n;  
  4.   // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer  
  5.   int SKIP_BUFFER_SIZE = 2048;  
  6.   // skipBuffer is initialized in skip(long), if needed.  
  7.   byte[] skipBuffer = null;  
  8.   int nr = 0;  
  9.   if (skipBuffer == null) {  
  10.    skipBuffer = new byte[SKIP_BUFFER_SIZE];  
  11.   }  
  12.   byte[] localSkipBuffer = skipBuffer;  
  13.   if (n <= 0) {  
  14.    return 0;  
  15.   }  
  16.   while (remaining > 0) {  
  17.    try {  
  18.     nr = inputStream.read(localSkipBuffer, 0,  
  19.       (int) Math.min(SKIP_BUFFER_SIZE, remaining));  
  20.    } catch (IOException e) {  
  21.     e.printStackTrace();  
  22.    }  
  23.    if (nr < 0) {  
  24.     break;  
  25.    }  
  26.    remaining -= nr;  
  27.   }  
  28.   return n - remaining;  
  29.  }  

其实这个方法和Java 官方源码的 skip 方法完全一样,只不过多加了一个 InputStream 的参数,当使用 inputStream来跳过 n  个字节时,可以使用
个方法。 唯一不明白的就是不知道为什么同样一个方法,放在java 源码中调用会失败,但是自己写的 完全正常,求解...

不过上面的方法一般可以用来读取本地文件,但是如果是从网络下载资源的话,上述方法就根本没有实用性了(比如断点续传)。 现在找到一个比 较规
的方法:
  1. HttpURLConnection con = null;  
  2.   try {  
  3.    con = (HttpURLConnection) u.openConnection();  
  4.    con.setConnectTimeout(10000);// 设置连接超时为10秒  
  5.    con.setRequestMethod("GET");  
  6.    // 设置断点续传得起始与终止位置  
  7.    long realPos = startPos + pausePos;  
  8.    con.setRequestProperty("Range""bytes=" + realPos + "-" + endPos);  
  9.    con.setUseCaches(true);  
  10.    InputStream inStream = con.getInputStream();//得到输入流  
  11.   } catch (Exception exc) {  
  12.   }  

上面的方法就是使用HTTP来设置一个文件的下载范围(realPos-endPos),这样,从网络向下传输的时候,就会自动从realPos 开始 传输数据流,一直
到endPos为止

TAGS:Java.IO.InputStream.skip()

猜你喜欢

NewHot