【问题标题】:Java: Is it possible to open a file for writing, but blow up if the file already exists?Java:是否可以打开文件进行写入,但如果文件已经存在则炸毁?
【发布时间】:2012-09-19 20:09:18
【问题描述】:

如果具有给定名称的文件已经存在,我想创建一个用于写入的文件并获取异常。我正在寻找一个线程安全的实现,并希望在 Java 标准库中。我找到的最接近的电话是这样的:

FileOutputStream fos = new FileOutputStream("/some/file/path.txt");

但这会截断同名的现有文件。如果已经存在同名文件,是否有任何方法会抛出异常或返回错误?

【问题讨论】:

    标签: java file-io


    【解决方案1】:

    尝试使用 File 类和createNewFile

    以下解决方案是线程安全的:

    File file = new File("/some/file/path.txt");
    if (file.createNewFile()) {
      // Succesfully created a new file
      FileOutputStream fos = new FileOutputStream(file);
      try {
        // Do something with outputstream
      } finally {
        try { fos.close(); } catch (IOException exception) { }
      }
    }
    

    【讨论】:

    • 我认为这已经足够接近了,但彼得指出了一个遗留问题。
    • 你能澄清一下这比只检查file.exists() 更好吗?这似乎更直接地解决了核心问题——“文件是否已经存在”。这两种方法都不是真正的事务性(我不能保证只有 1 个线程/进程可以在同一个文件上打开 FileOutputStream),我猜这是我们理想的情况。
    • 好的,我的问题的答案在 Javadoc 中:“createNewFile 原子地创建一个新的空文件...当且仅当具有此名称的文件尚不存在时。检查文件的存在和文件的创建(如果文件不存在)是单个操作,相对于可能影响文件的所有其他文件系统活动而言是原子的。”
    【解决方案2】:

    这是你想要的方法:File.createNewFile

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

    【讨论】:

      【解决方案3】:

      你可以

      • 检查文件是否存在
      • 如果它不写入临时文件
      • 将临时文件重命名为原始文件
      • 如果临时文件重命名失败,请删除它。

      由于第三步在操作系统中是原子的,所以它的线程和进程是安全的。

      【讨论】:

        【解决方案4】:
        File f = new File("/some/file/path.txt");
        if(f.exists()) 
          {
           //delete the file
          }
           else
          {
            //create and do what you want
          }
        

        【讨论】:

          【解决方案5】:

          是的,还有另一种方法,它也可以轻松地与您的代码集成:

          synchronized(this) {
            File f = new File("path");
          
            if (f.exists())
              throw new FileExistsException();
            else {
              FileOutputStream fos = new FileOutputStream(f);
              ...
            }
          }
          

          【讨论】:

          • 哦,没读过线程安全,让我们把所有的东西都放在一个同步块中,你就完成了。或者您可以使用互斥锁或锁,但这是一个与一般并发相关的问题,而不是文件存在。
          • 如果不以跨平台方式使用外部锁(可以是锁文件或其他任何东西),您将无法确定两个进程。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-06
          • 2023-04-11
          • 2014-06-30
          相关资源
          最近更新 更多