一个文件同步读写的故事

需求:读写目标文件为同一个(是一张从摄像头拿到的数据存成的图片),读文件时候要确保没有在被写(否则可能拿到部不完整的数据)。高频写,低频读。

1、如网上所说,用FileLock,类似如下

FileOutputStream outStream = new FileOutputStream(file);//或者
outStream.getChannel().lock();

但是问题是这里的lock是channel的lock,同一个文件可以有多个channel,而我的读写不在同一个线程,没办法使用同一个channel。

2、使用信号量,直接上最终代码了,中间经历过优化,主要是tryAcquire和Acquire的区别。

import android.util.Log;

import java.io.File;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class FrameImageLock {
    private static final String TAG = FrameImageLock.class.getSimpleName();
    private Semaphore lock;
    private File file;

    private FrameImageLock() {
        lock = new Semaphore(1);
        file = new File(Constants.CURRENT_FRAME);
        FileUtil.checkFileExistOrCreate(file);
    }

    private static class InstanceHolder {
        public static FrameImageLock instance = new FrameImageLock();
    }

    public static FrameImageLock getInstance() {
        return InstanceHolder.instance;
    }

    public File tryAcquire() {
        try {
            if (lock.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
                return file;
            } else {
                Log.e(TAG, ":timeout");
            }
        } catch (InterruptedException e) {
            Log.e(TAG, ":interrupted");
        }
        return null;
    }

    public File acquireImmediately() {
        try {
            if (lock.tryAcquire(0, TimeUnit.MILLISECONDS)) {
                return file;
            } else {
                Log.e(TAG, " file is in use");
            }
        } catch (InterruptedException ignored) {
        }
        return null;
    }

    public void release() {
        lock.release();
    }
}

一个方法,看下能不能拿到文件的使用权,能就用,不能就算了。另一个方法看看,不行就等1秒,超时再作罢。

可以实现:缺点,高频使用信号量(目标文件是摄像头数据,可能30FPS),性能问题。设计问题,只能针对性的保护目标文件。代码不能复用。

3、有大神教我用队列,和我文章开头说的读写频率不符合。弃之。

4、后续在看怎么优化,看到有人说用RandomAccessFile,还没了解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值