2010-07-29 27 views
6

Tôi đang sử dụng mã như sau để kiểm tra xem tệp đã được tạo trước khi tiếp tục hay không, tệp được hiển thị trong trình duyệt tệp trước khi nó được được phát hiện bởi stat ... có vấn đề gì với việc này không?sử dụng stat để phát hiện xem tệp có tồn tại (chậm không?)

//... do something 

struct stat buf; 

while(stat("myfile.txt", &buf)) 
    sleep(1); 

//... do something else 

cách khác để kiểm tra xem tệp có tồn tại hay không?

+0

tập tin gì? Viết tập tin là gì? Bạn có chắc tệp không được viết dưới tên hơi khác và sau đó được đổi tên vào giây phút cuối cùng không? –

+0

Tôi đang sử dụng konqueror, nhưng cá heo cũng thông báo cho tôi sớm hơn stat. tệp được viết bởi ứng dụng tôi đã viết, vì vậy tôi biết nội dung và vị trí cần được viết. Ngoài ra, tập tin là một tập tin trống tôi đang viết chỉ để báo hiệu rằng một quá trình đã hoàn thành. –

+0

Thời gian trễ này là bao lâu? Là nó trên thứ tự của micro giây, hoặc phút? Không nên có lý do tại sao 'stat()' không thể chỉ ra tệp tồn tại khi nó thực sự. Tôi nghi ngờ có cái gì khác đang xảy ra ở đây mà bạn chưa được công nhận. –

Trả lời

3

Cuộc gọi hệ thống "stat" đang thu thập thông tin khác về tệp, chẳng hạn như, một số liên kết cứng trỏ đến nó hoặc số "inode" của nó. Bạn có thể muốn xem cuộc gọi hệ thống "truy cập" mà bạn có thể sử dụng để thực hiện kiểm tra sự tồn tại chỉ bằng cách chỉ định cờ "F_OK" trong "chế độ".

Tuy nhiên, có một vấn đề nhỏ với mã của bạn. Nó đặt quá trình để ngủ cho một thứ hai mỗi khi nó kiểm tra các tập tin mà không tồn tại được nêu ra. Để tránh điều đó, bạn phải sử dụng API inotify, theo đề xuất của Jerry Coffin, để nhận thông báo bằng hạt nhân khi tệp bạn đang chờ ở đó. Hãy nhớ rằng inotify không thông báo cho bạn nếu tập tin đã có, vì vậy trên thực tế bạn cần sử dụng cả "truy cập" và "inotify" để tránh tình trạng chạy khi bạn bắt đầu xem một tệp ngay sau khi tệp được tạo.

Không có cách nào tốt hơn hoặc nhanh hơn để kiểm tra xem tệp có tồn tại hay không. Nếu trình duyệt tệp của bạn vẫn hiển thị tệp nhanh hơn một chút so với chương trình này phát hiện ra, thì ý tưởng đổi tên của Greg Hewgill có thể đang diễn ra.

Đây là một mã C++ ví dụ mà thiết lập một hồ inotify, kiểm tra nếu tập tin đã tồn tại và chờ đợi cho nó bằng cách khác: Trình duyệt

#include <cstdio> 
#include <cstring> 
#include <string> 

#include <unistd.h> 
#include <sys/inotify.h> 

int 
main() 
{ 
    const std::string directory = "/tmp"; 
    const std::string filename = "test.txt"; 
    const std::string fullpath = directory + "/" + filename; 

    int fd = inotify_init(); 
    int watch = inotify_add_watch (fd, directory.c_str(), 
            IN_MODIFY | IN_CREATE | IN_MOVED_TO); 

    if (access (fullpath.c_str(), F_OK) == 0) 
    { 
     printf ("File %s exists.\n", fullpath.c_str()); 
     return 0; 
    } 

    char buf [1024 * (sizeof (inotify_event) + 16)]; 
    ssize_t length; 

    bool isCreated = false; 

    while (!isCreated) 
    { 
     length = read (fd, buf, sizeof (buf)); 
     if (length < 0) 
      break; 
     inotify_event *event; 
     for (size_t i = 0; i < static_cast<size_t> (length); 
      i += sizeof (inotify_event) + event->len) 
     { 
      event = reinterpret_cast<inotify_event *> (&buf[i]); 
      if (event->len > 0 && filename == event->name) 
      { 
       printf ("The file %s was created.\n", event->name); 
       isCreated = true; 
       break; 
      } 
     } 
    } 

    inotify_rm_watch (fd, watch); 
    close (fd); 
} 
+0

một câu hỏi, là ngủ (1) một vấn đề lớn ... một vài giây tụt hậu không phải là một vấn đề, và đó là điều tôi mong đợi nhất từ ​​việc thêm vào các cuộc gọi giấc ngủ. –

+0

Không, loại bỏ giấc ngủ chỉ là một sự theo đuổi sự xuất sắc hơn là một vấn đề giải quyết nếu chúng ta đang nói về sự chậm trễ từ 10 đến 60 giây ở đây. Greg Hewgill đặt câu hỏi đúng về bản sao giống như NFS và các máy khác nhau. Những thứ đó là nguyên nhân có thể xảy ra nhất. Ngoài ra, có một cuộc gọi hệ thống "waitpid" mà bạn có thể sử dụng để chờ quá trình kết thúc thay vì tạo/bỏ phiếu một tệp. –

+0

Điều này cũng có một điều kiện chủng tộc trong thực tế là không có đảm bảo rằng tập tin tồn tại sau khi các cuộc gọi chức năng thông báo OR truy cập. Chỉ tại thời điểm cuộc gọi. Và trên thực tế, thử nghiệm để xem liệu một tập tin tồn tại có lẽ nên tránh. Bạn nên giả sử tệp tồn tại và xử lý trường hợp nếu bạn không thể truy cập hoặc mất nó trong khi làm việc với nó. Ví dụ 1: Tệp tồn tại nhưng bạn không có quyền truy cập. Ví dụ 2: Tệp "biến mất" vì giá trị biến mất (NFS). – Rahly

4

Sử dụng inotify, bạn có thể sắp xếp hạt nhân thông báo cho bạn khi thay đổi hệ thống tệp (chẳng hạn như tạo tệp) diễn ra. Điều này cũng có thể là những gì trình duyệt tệp của bạn đang sử dụng để biết về tệp quá nhanh.

1

mã của bạn sẽ kiểm tra xem tệp có tồn tại sau mỗi giây không. bạn có thể sử dụng inotify để nhận sự kiện thay thế.

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