写入文件前如何在Java中锁定文件夹?

时间:2018-07-05 05:47:32

标签: java file concurrency synchronization

我有多个线程可以将文件写入文件夹的用例。在给定的时间点,我想确定哪个是该文件夹中的最新文件。 由于我无法使用时间戳记,因为文件夹中的多个文件可以使用相同的时间戳记。因此,我想锁定文件夹,通过计算文件夹中文件的数量来生成序列号,使用生成的序列号写入新文件,然后释放锁定。在Java中有可能吗?

类似地,读取序列号最大的文件。

同时将文件写入文件夹的机会较少,因此性能不会成为问题。

3 个答案:

答案 0 :(得分:1)

您不能在目录上使用FileLock,因此必须处理Java中的锁定。您可以执行以下操作:

<?php
header('Access-Control-Allow-Origin: *'); 
?>

注意

您可以实现您的解决方案,以便每次写入都在某个位置增加一个计数器,您可以使用该计数器来获得下一个值;如果计数器尚未初始化,则仅排序并查找最后一个文件。

答案 1 :(得分:0)

使用Java SE 7或更高版本:

WatchService API允许跟踪指定目录中的文件操作(创建,修改和删除文件)。在这种情况下,创建监视服务以跟踪在特定文件夹中创建的新文件。每次创建新文件时,都会触发创建事件的文件,并且该过程允许执行一些用户定义的操作。

该文件已经具有创建的时间属性(java.nio.file.attribute.BasicFileAttributes)。可以从类型为java.nio.file.attribute.FileTime的类型中提取出来,类型为 millis ,也可以是更具体的java.util.concurrent.TimeUnit(这允许 nanosecond 精度)。这样可以更具体地了解最新文件。

此外,还有一个选项可以为任何文件创建自定义的用户定义的文件属性。该属性允许定义为键值对。可以将此唯一属性值与文件关联,以识别文件是否为最新文件。以下API允许创建和读取自定义文件属性:java.nio.file.attribute.UserDefinedFileAttributeViewFiles.getFileAttributeView()

我认为,使用上述API和方法,可以创建一个应用程序来跟踪在指定文件夹中创建的最新文件并执行所需的操作。请注意,如果使用这些API,则不会涉及锁定机制。

编辑(包括):

使用集合来检索最新文件:

线程安全集合可用于存储文件名(或文件路径)并检索LIFO(后进先出)。监视服务(或类似过程)可以将在文件夹中创建的(最新)文件的文件名存储到此集合。读取操作仅从该集合中获取最新文件名并使用它。人们可以根据需要考虑使用java.util.concurrent.ConcurrentLinkedDequeLinkedBlockingDeque

编辑(包括):

可能的解决方案流程图:

enter image description here

答案 2 :(得分:0)

在循环中使用File.createNewFile()进行编写。因为它

  

当且仅当具有该抽象路径名的文件尚不存在时,以原子方式创建一个新的空文件。检查文件是否存在以及是否创建文件(如果文件不存在)是单个操作,对于可能影响文件的所有其他文件系统活动而言,这是原子操作。

赞:

import java.io.*;
import java.util.*;

public class FileCreator {
    public static void main(String[] args) throws IOException {
        String creatorId = UUID.randomUUID().toString();
        File dir = new File("dir");
        for (int filesCreated = 0; filesCreated < 1000; filesCreated++) {
            File newFile;
            for (int fileIdx = dir.list().length; ; fileIdx++) {
                newFile = new File(dir, "file-" + fileIdx + ".txt");
                if (newFile.createNewFile()) {
                    break;
                }
            }
            try (PrintWriter pw = new PrintWriter(newFile)) {
                pw.println(creatorId);
            }
        }
    }
}

另一个选项是Files.createFile(...)。如果文件已经存在,它将引发异常。

阅读:

  

类似地,读取序列号最大的文件。

这里有什么问题?只需接受即可。