1

有一个文件可以被多线程以随机顺序访问,如何确保文件只从磁盘加载一次以减少 Java 中的文件 io 成本?

谢谢。

4

2 回答 2

4

我会这样做

private final Map<File, byte[]> cache = new HashMap<File, byte[]>();

public synchronized byte[] readFile(File file) throws IOException {
    byte[] content = cache.get(file);
    if (content == null) {
        content = Files.readAllBytes(file.toPath());
        cache.put(file, content);
    }
    return content;
}

更新

这个版本应该允许异步读取

private final Map<File, byte[]> cache = new HashMap<File, byte[]>();
private final Map<File, Object> locks = new HashMap<File, Object>();

public byte[] readFile(File file) throws IOException {
    Object lock = getLock(file);
    synchronized (lock) {
        byte[] content = cache.get(file);
        if (content == null) {
            content = Files.readAllBytes(file.toPath());
            cache.put(file, content);
        }
        return content;
    }
}

private synchronized Object getLock(File file) {
    Object lock = locks.get(file);
    if (lock == null) {
        lock = new Object();
        locks.put(file, lock);
    }
    return lock;
}
于 2013-04-26T03:37:54.017 回答
0

好吧,您可以跟踪当前正在访问的文件...

public static final long FILE_LOCKED = -1;

private static Set<File> lockedFiles = new HashSet<File>();

private byte[] fileContent;

private synchronized boolean acquireFileLock(File file) {
    if(lockedFiles.contains(file) {
        return false;
    }

    lockedFiles.add(file);
    return true;
}

public long readFile(File file) {
    if(acquireFileLock(file)) {
        // read your File into fileContnent
        lockedFiles.remove(file);
        return bytesRead;
    } else {
        return FILE_LOCKED;
}
于 2013-04-26T04:25:38.270 回答