2009-10-12 86 views
9

我试图用Java实现以下的操作,我不知道如何:如何在Java中创建文件,只有当文件不存在时才能创建文件?

/* 
* write data (Data is defined in my package) 
* to a file only if it does not exist, return success 
*/ 
boolean writeData(File f, Data d) 
{ 
    FileOutputStream fos = null; 
    try 
    { 
     fos = atomicCreateFile(f); 
     if (fos != null) 
     { 
      /* write data here */ 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    finally 
    { 
     fos.close(); // needs to be wrapped in an exception block 
    } 
} 

是否有存在已经是我可以用atomicCreateFile()功能?

编辑:呃哦,我不确定File.createNewFile()是否足以满足我的需求。如果我打电话给f.createNewFile(),然后在它返回的时间和我打开文件进行写作之间,其他人删除了该文件,该怎么办?有没有一种方法可以创建文件并打开它来写入或锁定它,一举一动?我需要担心这个吗?

回答

18

File.createNewFile()只有当文件不存在时才会创建文件。

编辑:根据您想要在文件创建后锁定的新描述,您可以使用java.nio.channels.FileLock对象来锁定文件。虽然没有像你希望的那样创建和锁定一行。另请参阅此SO question

+0

卫生署!我怎么错过了? :/ 谢谢。我的思想一直在C++领域。 – 2009-10-12 18:33:59

+0

根据您的编辑更新了我的答案 – 2009-10-12 18:48:14

+0

好的,谢谢。好吧,这听起来像我必须仔细考虑特殊情况。 (例如。如果createNewFile()成功,但打开一个文件通道并获得文件锁定失败) – 2009-10-12 18:53:43

7

File.createNewFile()

以原子创建此抽象路径名当且仅当这个名字文件尚不存在命名一个新的空文件。检查文件是否存在以及文件是否存在(如果文件不存在)的检查是针对可能影响文件的所有其他文件系统活动的原子操作。

编辑

杰森,为您的关注,如果您继续阅读我们给您发送的链接有一个关于该注。

注:该方法不应当被用于文件锁定,因为所得协议不能进行可靠地工作。应该使用FileLock设施。

,我认为你应该阅读这部分太:

alt

+0

Joachim:没问题,所以使用乐观锁进行编辑 – OscarRyz 2009-10-12 18:59:54

+0

谢谢,我确实读过注释,这就是触发呃哦。 – 2009-10-12 19:19:21

+0

(不幸的是,似乎没有Java I/O范例的存储库,除了手动探索平台javadocs,它说这些都是你可用的所有工具... File和FileLock有完全不同的包,有时你使用FileChannel,有时你使用FileOutputStream ...有时让我的头旋转。) – 2009-10-12 19:21:41

-1

为什么你就不能使用测试File#exists

+6

,因为在使用File.exists()进行测试的时间间隔内,如果文件不存在,您可以创建文件,而其他人可能先创建文件。 – 2009-10-12 18:34:30

+5

因为当exists()返回false时,他构造了'FileOutputStream',其他进程可以跳入并创建文件。经典的竞赛条件。 – 2009-10-12 18:34:30

+18

(与我在Joachim之前的评论中一样):-) – 2009-10-12 18:35:45

-2
//myFile should only be created using this method to ensure thread safety 
public synchronized File getMyFile(){ 
    File file = new File("path/to/myfile.ext"); 
    if(!file.exists()){ 
    file.getParentFile().mkdirs(); 
    file.createNewFile(); 
    } 
    return file; 
} 
+0

我将参数更改为File构造函数为实际字符串,以防因此而失败。 – cosbor11 2015-03-09 06:40:57

+0

当系统正在创建一个文件时,它会有一个句柄,即“锁定”。 – cosbor11 2015-03-09 06:41:37

+0

当你写入文件时,它也应该得到一个File对象的句柄,所以没有其他线程可以访问它或删除它。你可以写一个JUnit测试来确认这一点。如果遇到任何问题,您可以在synconized(){}块中运行您的操作。 – cosbor11 2015-03-09 06:43:34

2

Java 7的版本Files#createFile

Path out; 

try { 
    out = Files.createFile(Paths.get("my-file.txt")); 
} catch (FileAlreadyExistsException faee) { 
    out = Paths.get("my-file.txt"); 
}