2009-09-05 27 views
61

Tôi đã có một my_file fstream ("test.txt"), nhưng tôi không biết nếu test.txt tồn tại. Trong trường hợp nó tồn tại, tôi muốn biết nếu tôi có thể đọc nó, quá. Làm thế nào để làm điều đó?Làm cách nào để kiểm tra xem tệp có tồn tại và có thể đọc được trong C++ không?

Tôi sử dụng Linux.

+0

ở đâu "có thể trùng lặp". Tôi tự hỏi, nếu con cái của chúng tôi sẽ hỏi câu hỏi này? – SChepurin

Trả lời

80

tôi có lẽ sẽ đi với:

ifstream my_file("test.txt"); 
if (my_file.good()) 
{ 
    // read away 
} 

Các good kiểm tra phương pháp nếu dòng sẵn sàng để được đọc từ.

+12

Bằng cách này bạn không chỉ kiểm tra xem nó tồn tại và có thể đọc được, bạn thực sự mở nó. – xtofl

+1

Vâng, đó là sự thật. Tôi đọc câu hỏi của OP rằng tập tin đã được mở anyway, nhưng tôi có thể sai. –

10

Hệ điều hành/nền tảng nào?

Trên Linux/Unix/MacOSX, bạn có thể sử dụng fstat.

Trên Windows, bạn có thể sử dụng GetFileAttributes.

Thông thường, không có cách nào để thực hiện điều này với chức năng IO C/C++ chuẩn.

+1

Tại sao bạn nói rằng, bạn luôn có thể chỉ cần cố gắng để mở một tập tin với fopen và nếu nó trả về 0 bạn có thể suy ra portably rằng tập tin là không tồn tại. – Blindy

+1

fstat cũng có sẵn trên windows, trong 'sys/stat.h'. – xtofl

8

nếu bạn bật unix thì access() có thể cho bạn biết nếu nó có thể đọc được. Tuy nhiên nếu ACL đang được sử dụng, thì nó trở nên phức tạp hơn, trong trường hợp này tốt nhất là chỉ mở tệp bằng ifstream và thử đọc .. nếu bạn không thể đọc thì ACL có thể cấm đọc.

+1

access() là một cách tuyệt vời để giới thiệu các lỗi thời gian kiểm tra thời gian sử dụng. – bk1e

23

Bạn có thể sử dụng Boost.Filesystem. Nó có chức năng boost::filesystem::exist.

Tôi không biết cách kiểm tra quyền truy cập đọc. Bạn cũng có thể xem trong số Boost.Filesystem. Tuy nhiên có khả năng sẽ không có cách nào khác (di động) hơn là thực sự đọc tệp.

+0

Hệ thống tập tin có tăng cường xử lý các đường dẫn rất dài trên các cửa sổ (> 256) không? Gần đây, chúng tôi đã gặp phải sự cố là API cửa sổ không unicode có tối đa 256 ký tự. –

+0

Tôi không biết. Bạn có thể kiểm tra trong tài liệu (tại liên kết trong câu trả lời của tôi) nhưng tôi không chắc chắn cho dù bạn sẽ tìm thấy nó và lâu dài của nó. Bạn cũng có thể yêu cầu nhóm tin tức Boost. Một cách khác là chỉ cần kiểm tra nó. –

+0

@Richard Corden Tôi đã kiểm tra các đường dẫn rất dài với chức năng tăng :: filesystem :: create_directories. Phiên bản ANSI (cho char) đã ném một ngoại lệ nếu được cho đường dẫn dài (nhưng giới hạn bằng cách nào đó đạt khoảng 250 thay vì sau đó MAX_PATH đó là bằng 260). Phiên bản UNICODE (cho wchar_t) đã tạo nhiều thư mục như phiên bản ANSI mà không cần ném và trả về thành công để không chỉ nó không thực hiện công việc mà còn không báo cáo lỗi. Tôi không biết làm thế nào là nó với các chức năng khác, nhưng tôi nghi ngờ bây giờ họ có thể hành xử xấu là tốt. –

0

Liên quan đến việc sử dụng fstat trong cửa sổ, tôi không chắc chắn nếu đó là những gì bạn muốn. Từ Microsoft tệp phải được mở. Stat sẽ hoạt động cho bạn.

2

Tôi biết người đăng ký cuối cùng cho biết họ đang sử dụng Linux, nhưng tôi rất ngạc nhiên khi không ai đề cập đến cuộc gọi API PathFileExists() cho Windows.

Bạn cần phải bao gồm thư viện Shlwapi.lib và tệp tiêu đề Shlwapi.h.

#pragma comment(lib, "shlwapi.lib") 
#include <shlwapi.h> 

hàm trả về một giá trị BOOL và có thể được gọi như vậy:

if(PathFileExists("C:\\path\\to\\your\\file.ext")) 
{ 
    // do something 
} 
+0

Tôi đã chạy trên các tuyên bố rằng PathFileExists() không đáng tin cậy: http://mfctips.com/tag/file-exists/ –

3

Kể từ C++ 11 nó có thể sử dụng ngầm operator bool thay vì good():

ifstream my_file("test.txt"); 
if (my_file) { 
    // read away 
} 
Các vấn đề liên quan