2010-12-27 51 views
6

Trong C khi chúng ta mở một tệp gì xảy ra? Như tôi biết rằng nội dung của tệp không được tải trong bộ nhớ khi chúng tôi mở tệp. Nó chỉ đặt bộ mô tả tập tin? Vậy bộ mô tả tập tin này là gì ?? Và nếu nội dung của tập tin không được tải trong bộ nhớ thì làm thế nào một tập tin được mở ra?Mở một tệp bằng C là gì?

+2

Bạn đang sử dụng chức năng nào để mở tệp? – Thanatos

Trả lời

2

C không có tệp gốc cho tệp I/O, tất cả phụ thuộc vào hệ điều hành và thư viện nào bạn đang sử dụng.

+2

'fopen' là nguyên thủy của C đối với tệp I/O và không phụ thuộc vào hệ điều hành. (Mặc dù bạn thường có thể thực hiện cuộc gọi đến các chức năng cụ thể của hệ điều hành để kiểm soát nhiều hơn.) – Thanatos

+1

Điều đó không hoàn toàn chính xác. 'fopen' là một hàm thư viện, không phải là nguyên thủy. Ngoài ra, kể từ khi truy cập tập tin luôn luôn được thực hiện bởi hệ điều hành, 'fopen' thực sự là hệ điều hành phụ thuộc. Trên một hệ điều hành 'fopen' có thể đọc trước hoặc ghi đệm, trên một hệ điều hành khác có thể không. –

+0

không chỉ vậy, nhưng định dạng của chuỗi fopen đề cập đến là hoàn toàn phụ thuộc vào hệ điều hành. Ba lựa chọn phổ biến sử dụng/\ hoặc: là – ddyer

1

Trình mô tả tệp chỉ tóm tắt. Mọi thứ được thực hiện trên hệ điều hành.

0

Như đã đề cập, đó là chức năng OS.

Nhưng đối với tệp C/I/O có thể bạn cần thông tin về chức năng fopen.

Nếu bạn sẽ kiểm tra mô tả cho chức năng đó, nó nói:

Mô tả:

Mở một stream.

fopen mở tệp có tên là tên tệp và liên kết luồng với . fopen trả về một con trỏ được sử dụng để xác định luồng trong các hoạt động tiếp theo.

Vì vậy, khi hoàn tất thành công fopen chỉ trả về một con trỏ tới luồng mới được mở. Và nó trả về NULL trong trường hợp có lỗi.

6

Thông thường, nếu bạn đang mở một tập tin với fopen hoặc (trên một hệ thống POSIX) open, chức năng, nếu thành công, sẽ "mở file" - nó chỉ đơn thuần là cung cấp cho bạn một giá trị (một FILE * hoặc một int) để sử dụng trong các cuộc gọi trong tương lai tới một chức năng đọc.

Dưới mui xe, hệ điều hành có thể đọc một số hoặc tất cả tệp trong đó, có thể không. Bạn phải gọi một số chức năng để yêu cầu dữ liệu được đọc anyways, và nếu nó đã không thực hiện nó theo thời gian bạn gọi fread/fgets/read/etc ... sau đó nó sẽ vào thời điểm đó.

Một "bộ mô tả tệp" thường đề cập đến số nguyên được trả về bởi open trong các hệ thống POSIX. Nó được sử dụng để xác định một tập tin mở. Nếu bạn nhận được giá trị 3, ở đâu đó, hệ điều hành đang theo dõi rằng 3 đề cập đến /home/user/dir/file.txt hoặc bất kỳ điều gì. Đó là một giá trị ngắn để chỉ ra cho hệ điều hành tệp cần đọc. Khi bạn gọi open, và mở nói, foo.txt, hệ điều hành nói, "ok, mở tập tin, gọi nó là 3 từ đây về".

1

Nếu chương trình sử dụng fopen() thì gói đệm sẽ sử dụng cuộc gọi hệ thống cụ thể triển khai để có bộ mô tả tệp và nó sẽ lưu trữ trong cấu trúc FILE.

Cuộc gọi hệ thống (ít nhất là trên Unix, Linux và Mac) sẽ xem xét (thường là) hệ thống tệp dựa trên đĩa để tìm tệp. Nó tạo ra các cấu trúc dữ liệu trong bộ nhớ hạt nhân thu thập thông tin cần thiết để đọc hoặc ghi tệp.

Nó cũng tạo một bảng cho mỗi quá trình liên kết với các cấu trúc dữ liệu hạt nhân khác cần thiết để truy cập tệp. Chỉ mục trong bảng này là một số nhỏ (thường). Đây là bộ mô tả tập tin được trả về từ cuộc gọi hệ thống đến tiến trình người dùng, và sau đó được lưu trữ trong cấu trúc FILE.

4

Câu hỏi này không hoàn toàn liên quan đến ngôn ngữ lập trình. Mặc dù thư viện không có tác động đến những gì xảy ra khi mở một tệp (sử dụng open hoặc fopen, ví dụ), hành vi chính đến từ hệ điều hành.

Linux và tôi giả định các hệ điều hành khác thực hiện đọc trước trong hầu hết các trường hợp. Điều này có nghĩa là tệp thực sự được đọc từ bộ nhớ vật lý ngay cả trước khi bạn gọi read cho tệp. Điều này được thực hiện như một tối ưu hóa, giảm thời gian đọc khi tệp thực sự được đọc bởi người dùng. Hành vi này có thể được kiểm soát một phần bởi lập trình viên, sử dụng cờ cụ thể cho các chức năng mở. Ví dụ, Win32 API CreateFile có thể chỉ định FILE_FLAG_RANDOM_ACCESS hoặc FILE_FLAG_SEQUENTIAL_SCAN để chỉ định truy cập ngẫu nhiên (trong trường hợp tệp không đọc trước) hoặc truy cập tuần tự (trong trường hợp đó hệ điều hành sẽ thực hiện khá tích cực đọc trước), tương ứng. Các API hệ điều hành khác có thể kiểm soát nhiều hơn hoặc ít hơn.

Đối với API ANSI C cơ bản là open, read, write sử dụng bộ mô tả tệp, bộ mô tả tệp là một số nguyên đơn giản được chuyển vào hệ điều hành và biểu thị tệp. Trong bản thân hệ điều hành này thường được dịch sang một số cấu trúc có chứa tất cả các thông tin cần thiết cho tệp (tên, đường dẫn, tìm kiếm bù đắp, kích thước, đọc và ghi bộ đệm, v.v.). Hệ điều hành sẽ mở tệp - nghĩa là tìm mục hệ thống tệp cụ thể (một inode trong Linux) tương ứng với đường dẫn bạn đã đưa ra trong phương thức open, tạo cấu trúc tệp và trả lại ID cho người dùng - bộ mô tả tệp. Từ thời điểm đó trên hệ điều hành là miễn phí để đọc bất kỳ dữ liệu có vẻ phù hợp, ngay cả khi không được yêu cầu bởi người dùng (đọc nhiều hơn được yêu cầu thường được thực hiện, ít nhất là làm việc trong kích thước bản gốc của hệ thống tập tin).

0

Khi bạn mở tập tin sau đó con trỏ tập tin được địa chỉ cơ sở (bắt đầu từ địa chỉ) điều đó file.Then bạn sử dụng chức năng khác nhau để làm việc trên các tập tin. EDIT: Nhờ Chris, đây là cấu trúc có tên FILE

typedef struct { 
     int    level;  /* fill/empty level of buffer */ 
     unsigned  flags;  /* File status flags   */ 
     char   fd;   /* File descriptor   */ 
     unsigned char hold;  /* Ungetc char if no buffer */ 
     int    bsize;  /* Buffer size    */ 
     unsigned char *buffer; /* Data transfer buffer  */ 
     unsigned char *curp;  /* Current active pointer  */ 
     unsigned  istemp;  /* Temporary file indicator */ 
     short   token;  /* Used for validity checking */ 
}  FILE; 
+0

Không chính xác. "Con trỏ tập tin" vào một luồng (có thể là một tệp theo nghĩa đen hoặc một cái gì đó khác) không thực sự là con trỏ đến dữ liệu của tệp, mà thay vào đó là một con trỏ tới cấu trúc lưu trữ thông tin truy cập bao gồm mô tả tệp cơ bản và con trỏ. Con trỏ đọc thường được khởi tạo vào đầu tệp. Nhưng hàm fopen() trả về một con trỏ tới cấu trúc, không phải là dữ liệu trong tệp. Để có được một con trỏ dereferencable thực tế để dữ liệu của tập tin, sử dụng mở() để có được một mô tả tập tin (chứ không phải là fopen()) và sau đó mmap() nó. –

+0

Cấu trúc tệp phụ thuộc vào hệ điều hành. Một số cấu trúc có thể chứa khu vực logic và số đĩa của phần đầu của tệp. Các tệp khác có thể chứa quyền và tên tệp. –

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