2013-04-12 25 views
7

Tôi đã phát hiện ra cơ chế khóa Tệp Java là một sai lầm thực sự vì nó không thể thực hiện quy tắc thứ nhất về khóa - chặn trên cuộc gọi để khóa! Trừ khi tôi sai - một cuộc gọi để khóa() sẽ ném một ngoại lệ nếu một ứng dụng đã duy trì một khóa trên tập tin, mà tôi biết sẽ là trường hợp trong ứng dụng của tôi. Tôi đã nhìn qua một số câu trả lời ở đây và không may tôi không sử dụng Java 7.Chặn tệp Java không có ngoại lệ; chờ đợi trên khóa

Có ai có đề xuất về làm thế nào tôi có thể xử lý chờ đợi vào một khóa tập tin độc quyền mà không đặt bản thân mình trong một vòng lặp while(true) :)

CHỈNH SỬA sau câu trả lời của Aubin (sao chép từ nhận xét):

Điều tôi muốn làm là truy cập một tệp lớn sau khi được sao chép vào một thư mục rồi xử lý. Mã của tôi rất đơn giản ...

public boolean ifFileReady(File file) { 
    boolean ready = false; 
    FileLock lock = null; 
    FileChannel channel = null; 
    try { 

     channel = new RandomAccessFile(file, "rw").getChannel(); 
     lock = channel.lock(); 
     lock.release(); 
     ready = true; 
    } 
    catch(IOException e) { 
     // Always Here 
    } 
    finally 
    { 
     if (channel != null) 
     channel.close(); 
    } 
    return ready; 
} 

Tôi không bao giờ chặn khóa. Nó luôn luôn ném

+0

[Java 7 là bắt buộc ngay bây giờ] (http://www.oracle.com/technetwork/java/eol-135779.html) – Aubin

+0

Vui lòng đăng theo dõi ngăn xếp, vì IOException có thể có một số nguồn gốc hoặc nguyên nhân, như quyền truy cập từ chối. Hãy thử "r" chỉ trong 'RandomAccessFile (tập tin," rw ")' thay cho "rw". – Aubin

Trả lời

2

Bản sao documentation của java.nio.channels.FileChannel:

công khóa FileLock trừu tượng (vị trí dài, kích thước dài, boolean chia sẻ) throws IOException

Dành được một khóa trên khu vực nhất định của kênh này của tập tin.

Một gọi của phương pháp này sẽ chặn cho đến khi khu vực này có thể khóa, kênh này được đóng lại, hoặc các chủ đề cách gọi bị gián đoạn, nào đến trước.

Từ: 1,4

+0

Điều tôi muốn làm là truy cập một tệp lớn sau khi được sao chép vào một thư mục và sau đó xử lý nó. Mã của tôi rất đơn giản ... công khai boolean ifFileReady (Tệp tệp) { boolean ready = false; thử { kênh = new RandomAccessFile (tệp, "rw"). GetChannel(); lock = channel.lock(); khóa.giải phóng(); ready = true; } catch (IOException e) { // Luôn Ở đây }} tôi không bao giờ chặn tại khóa. Nó luôn luôn ném. – jiveturkey

+0

Vui lòng chỉnh sửa mã tôi đã dán trong câu hỏi của bạn vì khóa không được xác định và trả về bị thiếu. – Aubin

+0

Xin lỗi, tôi đã rất đau khổ. – jiveturkey

2

Các mã sau đây chứng minh rằng khóa không thực sự khối mà không cần ném một ngoại lệ. Tôi đã có một vấn đề tương tự nhưng phát hiện ra ngoại lệ đã được thực sự gây ra bằng cách mở rw tập tin khi người dùng của tôi không có quyền làm như vậy.

Đó là chương trình hoàn chỉnh; chạy hai trường hợp của nó đồng thời cho các cuộc biểu tình

import java.io.File; 
import java.io.RandomAccessFile; 
import java.nio.channels.FileChannel; 

public class Test { 
    public static void main(String args[]) throws Exception { 
    FileChannel channel = null; 
    File lockFile = new File("lock"); 
    System.out.println ("Opening file..."); 
    channel = new RandomAccessFile(lockFile, "rw").getChannel(); 
    System.out.println ("File open. Locking channel..."); 
    channel.lock(); 
    System.out.println ("Channel locked. Sleep for 30 seconds"); 
    Thread.sleep (30000); 
    System.out.println ("Process terminating"); 
    } 
} 

Để giữ consise mã tôi càng không bao gồm việc bẻ khóa, đóng cửa hoặc xử lý ngoại lệ (bạn sẽ nhận được một cảnh báo trình biên dịch). Tất cả các tài nguyên sẽ được hệ điều hành tự động phát hành khi quá trình thoát.

Các vấn đề liên quan