2009-10-12 30 views
9

Tôi đang cố gắng để thực hiện các hoạt động sau đây trong Java và không chắc chắn như thế nào:cách tạo tệp trong Java chỉ khi một tệp chưa tồn tại?

/* 
* 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 
    } 
} 

Có một chức năng mà đã tồn tại mà tôi có thể sử dụng cho atomicCreateFile()?

chỉnh sửa: Uh oh, tôi không chắc File.createNewFile() có đủ cho nhu cầu của tôi hay không. Nếu tôi gọi f.createNewFile() và sau đó giữa thời gian trả lại và tôi mở tệp để ghi, ai đó đã xóa tệp đó? Có cách nào tôi có thể tạo cả tập tin và mở nó để viết + khóa nó, tất cả trong một ngã swoop? Tôi có cần phải lo lắng về điều này?

Trả lời

18

File.createNewFile() chỉ tạo tệp nếu tệp chưa tồn tại.

EDIT: Dựa trên mô tả mới của bạn về việc muốn khóa tệp sau khi được tạo, bạn có thể sử dụng đối tượng java.nio.channels.FileLock để khóa tệp. Không có một dòng tạo ra và khóa mặc dù như bạn đang hy vọng. Ngoài ra, hãy xem SO question này.

+0

doh! làm thế nào tôi đã bỏ lỡ điều đó? :/ cảm ơn. Tâm trí của tôi ở trong đất C++. –

+0

đã cập nhật câu trả lời của tôi dựa trên chỉnh sửa của bạn –

+0

ok, cảm ơn. Có vẻ như tôi phải suy nghĩ cẩn thận về những điều kiện đặc biệt. (ví dụ.nếu createNewFile() thành công nhưng mở một kênh tập tin và nhận được một khóa tập tin không thành công) –

7

File.createNewFile()

nguyên tử tạo, tập tin rỗng mới có tên bằng tên đường dẫn trừu tượng này khi và chỉ khi một tập tin với tên này chưa tồn tại. Kiểm tra sự tồn tại của tệp và tạo tệp nếu nó không tồn tại là một hoạt động đơn lẻ là nguyên tử đối với tất cả các hoạt động hệ thống tệp khác có thể ảnh hưởng đến tệp.

EDIT

Jason, như đối với mối quan tâm của bạn, nếu bạn liên tục đọc các liên kết chúng tôi đã gửi cho bạn có một LƯU Ý về điều đó.

Lưu ý: phương pháp này không nên được sử dụng cho tập tin khóa, như giao thức kết quả là không thể được thực hiện để làm việc đáng tin cậy. Thay vào đó, sử dụng cơ sở FileLock.

Tôi nghĩ rằng bạn thực sự nên đọc phần đó quá:

alt

+0

Joachim: Không có vấn đề, vì vậy sử dụng khóa lạc quan để chỉnh sửa – OscarRyz

+0

Cảm ơn, tôi đã đọc ghi chú, đó là những gì kích hoạt Uh oh. –

+0

(Thật không may dường như không phải là một kho lưu trữ các mô hình Java I/O, ngoài việc khai thác thủ công nền tảng javadocs, mà nói đây là tất cả các công cụ bạn có sẵn ... File và FileLock nằm trong các gói hoàn toàn khác nhau, đôi khi bạn sử dụng FileChannel, đôi khi bạn sử dụng FileOutputStream ... đôi khi quay đầu.) –

-1

Tại sao bạn không thể kiểm tra bằng File#exists?

+6

bởi vì giữa thời gian bạn kiểm tra bằng File.exists() và bạn tạo một tệp nếu nó không tồn tại, có thể ai đó đã tạo tệp trước. –

+5

Bởi vì giữa thời gian 'exist()' trả về false và anh ta xây dựng 'FileOutputStream' một số tiến trình khác có thể nhảy vào và tạo tệp. Một điều kiện đua cổ điển. –

+18

(giống như cách tôi trượt trong nhận xét đó ngay trước Joachim. :-) –

-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

Tôi đã thay đổi tham số thành Trình tạo tệp thành chuỗi thực trong trường hợp đó là lý do tại sao nó không thành công. – cosbor11

+0

Khi hệ thống đang tạo một tệp, nó sẽ có một tay cầm còn gọi là "khóa" trên đó. – cosbor11

+0

Khi bạn ghi vào tập tin, nó cũng sẽ có được một xử lý trên đối tượng tập tin để không có chủ đề khác có thể truy cập nó hoặc xóa nó.Bạn có thể viết một bài kiểm tra JUnit để xác nhận điều này. Nếu bạn gặp phải bất kỳ vấn đề nào, bạn có thể chạy các hoạt động của mình trong một khối synconized() {}. – cosbor11

2

Java 7 phiên bản với Files#createFile:

Path out; 

try { 
    out = Files.createFile(Paths.get("my-file.txt")); 
} catch (FileAlreadyExistsException faee) { 
    out = Paths.get("my-file.txt"); 
} 
Các vấn đề liên quan