如何在写入文件之前锁定java中的文件夹?

如何在写入文件之前锁定java中的文件夹?,java,file,concurrency,synchronization,Java,File,Concurrency,Synchronization,我有一个多线程可以将文件写入文件夹的用例。在给定的时间点,我想确定哪个文件是该文件夹中的最新文件。 因为我不能使用时间戳,因为它可以用于文件夹中的多个文件。所以我想锁定文件夹,通过计算文件夹中文件的数量生成序列号,使用生成的序列号写入新文件,释放锁。这在java中可能吗 同样,在读取时,取序列号最大的文件 并发将文件写入文件夹的可能性较小,因此性能不会成为问题。您不能在目录上使用,因此必须在Java中处理锁定。你可以这样做: private final Object lock = new Obj

我有一个多线程可以将文件写入文件夹的用例。在给定的时间点,我想确定哪个文件是该文件夹中的最新文件。 因为我不能使用时间戳,因为它可以用于文件夹中的多个文件。所以我想锁定文件夹,通过计算文件夹中文件的数量生成序列号,使用生成的序列号写入新文件,释放锁。这在java中可能吗

同样,在读取时,取序列号最大的文件

并发将文件写入文件夹的可能性较小,因此性能不会成为问题。

您不能在目录上使用,因此必须在Java中处理锁定。你可以这样做:

private final Object lock = new Object();

public void writeToNext(String dirPath) {
    synchronized(lock) {
        File dir = new File(dirPath);
        List<File> files = Arrays.asList(dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return !pathname.isDirectory();
            }
        }));

        int numFiles = files.size();
        String nextFile = dir.getAbsolutePath() + File.separator + (numFiles + 1) + ".txt"; // get a path for the new file
        System.out.println("Writing to " + nextFile);
        // TODO write to file
    }
}
private final Object lock=new Object();
公共无效writeToNext(字符串目录路径){
已同步(锁定){
文件目录=新文件(目录路径);
List files=Arrays.asList(dir.listFiles(newfilefilter()){
@凌驾
公共布尔接受(文件路径名){
return!pathname.isDirectory();
}
}));
int numFiles=files.size();
String nextFile=dir.getAbsolutePath()+File.separator+(numFiles+1)+“.txt”//获取新文件的路径
System.out.println(“写入”+nextFile);
//TODO写入文件
}
}
注意

您可以实现您的解决方案,这样每次写入都会在某个地方增加一个计数器,您可以使用它来获取下一个值;如果计数器尚未初始化,则只能订购并查找最后一个文件。

使用Java SE 7或更高版本:

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

该文件已经有一个已创建的时间属性(
java.nio.file.attribute.BasicFileAttributes
)。这可以提取为
java.nio.file.attribute.FileTime
类型,单位为毫秒,也可以是更具体的
java.util.concurrent.TimeUnit
(这允许纳秒精度)。这使我们有机会更具体地了解什么是最新的文件

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

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

编辑(包括):

使用集合检索最新文件:

线程安全集合可用于存储文件名(或文件路径)并在后进先出(last-in-first-out)中检索它们。监视服务(或类似过程)可以将文件夹中创建的(最新)文件的文件名存储到此集合。读取操作只是从该集合中获取最新的文件名并使用它。可以考虑<代码> java > UTI.O.CONTRONE.LIKEDDEQ或<代码> LinkedBlockingDeque < /C> 编辑(包括):

可能的解决方案流程图:

在循环中用于写入。因为它

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

像这样:

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);
            }
        }
    }
}
import java.io.*;
导入java.util.*;
公共类FileCreator{
公共静态void main(字符串[]args)引发IOException{
字符串创建者ID=UUID.randomUUID().toString();
文件目录=新文件(“目录”);
对于(int filesCreated=0;filesCreated<1000;filesCreated++){
文件新建文件;
对于(int fileIdx=dir.list().length;;fileIdx++){
newFile=新文件(dir,“File-”+fileIdx+“.txt”);
if(newFile.createNewFile()){
打破
}
}
try(PrintWriter pw=newprintwriter(newFile)){
pw.println(创建者ID);
}
}
}
}
另一个选择是。如果文件已经存在,它将引发异常

至于阅读:

同样,在读取时,取序列号最大的文件


这里有什么问题?就拿着它。

你可以用一个锁文件来序列化访问。锁文件也可以用于文件夹吗?我建议你自己弄清楚什么是锁文件。你不能为其他进程的写入或读取锁定文件夹(只要你不使用操作系统的功能)。但是如果你有一个并发应用程序,你可以同步应用程序的线程。这个程序是唯一写入文件夹的程序,还是你也应该保护其他应用程序?这个程序是否有多个实例在运行,或者只是一个进程可以使用内存中的锁?上面的锁只会阻止线程内的并发。但在我的例子中,将有多个java进程写入此文件夹。您可以使用进程之间共享的资源来同步这些进程。例如,具有一个表的数据库,您可以从中读取数据,以检查是否有一个进程正在处理该文件夹。如果没有进入