Trong ấn bản thứ hai của "Ngôn ngữ lập trình C" bởi Kernighan và Ritchie, chúng triển khai phiên bản đơn giản của lệnh UNIX ls
(phần 8.6 "Ví dụ - Danh bạ", tr. 179). Với mục đích này, họ tạo ra giao diện sau cung cấp truy cập độc lập hệ thống vào tên và số inode của các tệp được lưu trữ trong một thư mục.Giao diện K & R để đọc các thư mục: cấu trúc DIR thừa?
#define NAME_MAX 14 /* longest filename component; */
/* system dependent */
typedef struct { /* portable director-entry */
long ino; /* inode number */
char name[NAME_MAX+1]; /* name + '\0' terminator */
} Dirent;
typedef struct { /* minimal DIR: no buffering, etc. */
int fd; /* file descriptor for directory */
Dirent d; /* the directory entry */
} DIR;
DIR *opendir(char *dirname);
Dirent *readdir(DIR *dfd);
void closedir(DIR *dfd);
Sau đó, họ triển khai giao diện này cho phiên bản 7 và hệ thống V UNIX.
opendir()
cơ bản sử dụng hệ thống gọiopen()
để mở một thư mục vàmalloc()
phân bổ không gian cho một cấu trúcDIR
. Trình mô tả tệp được trả về trướcopen()
sau đó được lưu trữ trong biến sốfd
trong số đóDIR
. Không có gì được lưu trữ trong thành phầnDirent
.readdir()
sử dụng cuộc gọi hệ thốngread()
để có được sự xâm nhập thư mục (hệ thống phụ thuộc vào) tiếp theo của một thư mục mở ra và bản sao cái thu được số inode và filename thành mộtDirent
cấu trúc tĩnh (để đó một con trỏ được trả về). Thông tin chỉ cần thiết bởireaddir()
là bộ mô tả tệp được lưu trữ trong cấu trúcDIR
.
Bây giờ câu hỏi của tôi: điểm của việc có một cấu trúc DIR
là gì? Nếu hiểu biết của tôi về chương trình này là chính xác thì thành phần Dirent
của DIR
không bao giờ được sử dụng, vậy tại sao không thay thế toàn bộ cấu trúc bằng bộ mô tả tệp và trực tiếp sử dụng open()
và close()
?
Cảm ơn.
Ps: Tôi biết rằng trên hệ thống UNIX hiện đại read()
không còn có thể được sử dụng trên thư mục nữa (tôi đã thử chương trình này trên Ubuntu 10.04), nhưng tôi vẫn muốn đảm bảo rằng tôi đã không bỏ qua điều gì đó quan trọng trong thí dụ.
Tính di động cũng là phỏng đoán đầu tiên của tôi nhưng sau khi suy nghĩ về điều đó, tôi không thấy làm thế nào 'DIR' có thể đóng góp cho điều này. Thông tin liên quan duy nhất mà nó có thể truyền cho 'readdir()' là bộ mô tả tập tin. Tôi vẫn không thấy việc sử dụng thành phần 'Dirent' trong' DIR'. Bất kể hệ thống nào, bất kỳ sự thực hiện nào của 'readdir()' đều có thể có một 'Dirent' tĩnh để nó có thể trả về một con trỏ, vì vậy đây không phải là một vấn đề về tính di động. Đúng là 'dirwalk()' truy cập nội dung của một 'Dirent', nhưng đây là một phần tử tĩnh từ' readdir() ', không phải là một trong' DIR'. Tôi có thiếu gì đó không? – qfab
Xin chào, có vẻ như bạn đã đúng. Tôi đoán là họ bắt đầu bằng cách xác định cấu trúc dữ liệu của họ (với một 'Dirent' bên trong 'DIR') nhưng cuối cùng không sử dụng nó. Nhóm các dữ liệu liên quan với nhau trong các cấu trúc là juju tốt. Một bài tập tốt sẽ là viết lại mã để sử dụng 'DIR.d' thay vì có người gọi' readdir() 'có con trỏ' Dirent' của riêng họ. – nmichaels
Vâng, đây là một lời giải thích hợp lý. Nhưng xem xét cuốn sách đã được xuất bản hơn 20 năm trước (ấn bản thứ 2), thật lạ lùng rằng một cái gì đó như thế này không được đề cập trong [errata] (http://cm.bell-labs.com/cm/cs/cbook/ 2ediffs.html). – qfab