2012-12-19 59 views
7

thể trùng lặp:
What’s the best way to check if a file exists in C? (cross platform)C, kiểm tra xem tệp có tồn tại mà không có khả năng đọc/ghi không?

tôi muốn kiểm tra xem một tập tin tồn tại hay không. Tôi đã thay đổi quyền truy cập của tệp thử nghiệm thành "chmod -r somefile". Tuy nhiên bây giờ nó nói rằng tập tin không tồn tại mặc dù nó tồn tại.

Vì vậy, tôi giả sử nếu tôi không có quyền đọc tôi không thể mở tệp bằng "fopen r". Nhưng điều đó có nghĩa là không có cách nào dễ dàng để biết một tập tin tồn tại hoặc không thể đọc/ghi?

Hoặc tôi đang thiếu thứ gì đó? Bất kỳ sự trợ giúp nào đều sẽ là tuyệt vời.

Cảm ơn!

int doesFileExist(const char* filename) 
{ 
    FILE* fptr = fopen(filename, "r"); 
    if (fptr != NULL) 
    { 
    fclose(fptr); 
    printf("File exists\n"); 
    return 1; 
    } 
    printf("File doesnt exist\n"); 
    return 0; 
} 

Cập nhật: Cảm ơn bạn vì những liên kết và giải thích tuyệt vời này!

+1

Um .. bạn đã kiểm tra 'errno' chưa? EDIT: thử này để có được một số thông báo lỗi: 'printf (" File không tồn tại:% s \ n ", strerror (errno));' không quên bao gồm 'errno.h' header. – Jack

+0

Đây là những gì tôi ghét về API stdio, bất cứ khi nào bạn cần làm điều gì đó không giống như thay đổi kích cỡ tệp hoặc di chuyển tệp mà không sao chép tệp và xóa tệp cũ, bạn sẽ không may về tính di động. – Thomas

Trả lời

18

fopen thực sự cố gắng mở tệp mà bạn không thể thực hiện nếu bạn không có quyền truy cập đọc. Để kiểm tra xem tệp có tồn tại mà không cần mở tệp hay không, hãy sử dụng stat; stat cung cấp cho bạn siêu dữ liệu về tệp và chỉ yêu cầu quyền truy cập đọc vào thư mục chứa tệp, chứ không phải chính tệp đó.

int doesFileExist(const char *filename) { 
    struct stat st; 
    int result = stat(filename, &st); 
    return result == 0; 
} 

Bạn có thể nhận được fancier bằng cách kiểm tra errno nếu result không phải là 0; nếu errnoENOENT thì tệp không tồn tại, nếu là ENOTDIR thì một phần của đường dẫn bạn cung cấp không phải là thư mục, nếu đó là EACCESS thì bạn không có quyền đọc trên một trong các thư mục trong đường dẫn và do đó stat không cung cấp cho bạn một câu trả lời, và như vậy. Ngoài ra, hãy lưu ý rằng nếu bạn đang ở trên một nền tảng với các liên kết tượng trưng (bất kỳ kiểu Unix hoặc Windows Vista hoặc mới hơn), bạn nên biết liệu bạn đang truy vấn về liên kết tượng trưng hay tệp nó trỏ đến . Nếu bạn gọi stat, thì bạn đang hỏi về tệp mà nó trỏ đến; nếu bạn có liên kết tượng trưng dir/link trỏ đến other/file thì stat sẽ trả lại kết quả về other/file (thường là điều bạn muốn, vì đó là những gì bạn sẽ nhận được nếu bạn mở tệp).Tuy nhiên, nếu bạn tò mò về chính liên kết (nếu bạn muốn biết "hiện có dir/link tồn tại, ngay cả khi other/file không?"), Thì bạn nên sử dụng lstat().

stat() hoạt động trên Windows dưới dạng trình bao bọc tương thích (họ thích bạn sử dụng _stat() và sẽ cảnh báo nếu bạn không), nhưng tốt hơn là sử dụng API nền tảng gốc. Trên Windows, có thể bạn nên sử dụng GetFileAttributes():

int doesFileExist(const char *filename) { 
    return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES; 
} 
-1

Trên Linux (và nhiều hệ thống khác), bạn có thể sử dụng opendir() và bạn bè để liệt kê các thư mục. Tôi đoán các tệp chỉ đọc sẽ hiển thị. Sẽ có các chức năng tương tự có sẵn trên các nền tảng khác.

1

Bạn không thực sự kiểm tra xem tệp có tồn tại ở đây ... Bạn đang kiểm tra xem bạn có thể mở tệp đó bằng quyền truy cập đọc hay không. Nó có thể không thành công vì các lý do khác với tệp không tồn tại. Như bạn đã thấy, bạn có thể không có quyền đọc. Nó cũng có thể là tập tin bị khóa.

Kiểm tra câu trả lời này:

What's the best way to check if a file exists in C? (cross platform)

Nó gợi ý sử dụng stat, mà nên làm việc trong hầu hết các trường hợp ngoại trừ nếu bạn không có đọc truy cập vào các thư mục trong đó các tập tin thường trú.

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