android下载时文件写入效率 RandomAccessFile

之前在写下载APK的代码,okhttp的方式下载,本地写入用的用的RandomAccessFile.

发现类似的app网络速度比我快不少.

后来查看,除了发现一些逻辑错误,还是找到了根本原因:RandomAccessFile每次写入都要访问磁盘,速度太慢了.跟不上4G的步伐.

于是找到了BufferedRandomAccessFile的网上示例.

放到了我的code里面.

public void write(int b) throws IOException
{
    if (this.curr_ >= this.hi_)
    {
        if (this.hitEOF_ && this.hi_ < this.maxHi_)
        {
            // at EOF -- bump "hi"
            this.hi_++;
        }
        else
        {
            // slow path -- write current buffer; read next one
            this.seek(this.curr_);
            if (this.curr_ == this.hi_)
            {
                // appending to EOF -- bump "hi"
                this.hi_++;
            }
        }
    }
    this.buff_[(int) (this.curr_ - this.lo_)] = (byte) b;
    this.curr_++;
    this.dirty_ = true;
    syncNeeded_ = true;
}

它是具有缓存作用的RandomAccessFile, 满足断点续传的同时,大大了提高了效率.

后来在实践过程中,发现无奈的是,超过256M的下载是无法用BufferedRandomAccesssFile实例化的,会内存溢出.BufferedRandomA

ccessFile提高了速度根本原因是通过FileChannel和MappedByteBuffer的一起使用,利用了缓存.

在网友的文章里面,找到了

RandomAccessFile也能和FileChannel以及MappedByteBuffer一起,于是尝试放弃BufferedRandomAccessFile.

直接用RandomAccessFiles,代码如下:

private RandomAccessFile/*BufferedRandomAccessFile*/ mDownLoadFile;
FileChannel channelOut = null;
MappedByteBuffer mappedBuffer = null;
// 获得下载保存文件
mDownLoadFile = new RandomAccessFile(filepath, FILE_MODE);
// Chanel NIO中的用法,由于RandomAccessFile没有使用缓存策略,直接使用会使得下载速度变慢,
channelOut = mDownLoadFile.getChannel();
// 使用缓存下载,在这里指定下载位置。
mappedBuffer = channelOut.map(FileChannel.MapMode.READ_WRITE, completedSize,
        responseBody.contentLength());

    ......
mappedBuffer.put(buffer, 0, length);

放弃了RandonmAccessFiles的seek和write方法.

最终实现了预期效果.

 

参考:

https://blog.csdn.net/hpb21/article/details/51270873

https://blog.csdn.net/silentbalanceyh/article/details/5252285

 

你可能感兴趣的:(Android)