Mô tả tập tin, giải thích bằng thuật ngữ đơn giản là gì?


383
  1. Điều gì sẽ là một mô tả đơn giản hơn về mô tả tập tin so với Wikipedia? Tại sao họ được yêu cầu? Nói, lấy các quy trình shell làm ví dụ và làm thế nào để áp dụng nó?

  2. Liệu một bảng quy trình có chứa nhiều hơn một mô tả tập tin. Nếu đúng thì tại sao?


3
Những gì về các khái niệm của stdin stdout stderr vv? Tôi có một ví dụ như nói quá trình trình duyệt đã mở và nó đã mở một số tệp tạm thời để hiển thị html của tôi. Quá trình sử dụng cùng một fd để đọc / ghi? Ngoài ra bảng quy trình ....... nó có các mục như con trỏ fd0 con trỏ fd1 con trỏ fd2 ..... điều đó có nghĩa là tất cả các tệp này đều nằm trong RAM? Tại sao con trỏ khác?
Nishant

43
Khi bạn mở một tệp, HĐH sẽ tạo một luồng đến tệp đó và kết nối luồng đó với tệp đã mở, trên thực tế, bộ mô tả đại diện cho luồng đó. Tương tự, có một số luồng mặc định được tạo bởi HĐH. Các luồng này được kết nối với thiết bị đầu cuối của bạn thay vì các tệp. Vì vậy, khi bạn viết một cái gì đó trong terminal, nó sẽ chuyển sang stdin stream và OS. Và khi bạn viết lệnh "ls" trên thiết bị đầu cuối, HĐH sẽ ghi đầu ra vào luồng đầu ra. luồng stdout được kết nối với thiết bị đầu cuối màn hình của bạn để bạn có thể thấy đầu ra ở đó.
Tayyab

1
Về ví dụ trình duyệt, không cần thiết trình duyệt giữ các tệp được mở. Nó phụ thuộc vào việc triển khai trình duyệt nhưng trong hầu hết các trường hợp trình duyệt mở một tệp tạm thời, ghi tệp và đóng tệp, do đó không cần thiết phải mở tệp ngay cả khi trang web đang mở. Và bộ mô tả chỉ chứa thông tin của tệp và không nhất thiết phải giữ tệp trong RAM. Khi bạn đọc dữ liệu từ một bộ mô tả, HĐH sẽ đọc dữ liệu từ đĩa cứng. Thông tin trong bộ mô tả tệp chỉ đại diện cho vị trí của tệp trên đĩa cứng, v.v.
Tayyab

5
Mô tả tệp cho tệp không phải là ánh xạ một đến một. Tôi có thể mở () cùng một tệp 4 lần và nhận được 4 mô tả tệp khác nhau. Mỗi trong số đó có thể được sử dụng (tùy thuộc vào các cờ được chuyển đến open ()) để đọc, viết hoặc cả hai. Theo như các tập tin sống trong RAM hoặc trên đĩa - điều này được ẩn khỏi bạn bởi kernel và các bộ nhớ cache khác nhau của nó. Cuối cùng, bộ đệm sẽ khớp với cái gì trên đĩa (để ghi) và kernel sẽ không quay trở lại đĩa, để đọc, nếu dữ liệu đã có trong bộ đệm.
Beano

7
Đây là một bài viết tốt để hiểu nó một cách dễ dàng bottomupcs.com/file_descriptors.xhtml
Krishan Gopal

Câu trả lời:


561

Nói một cách đơn giản, khi bạn mở một tệp, hệ điều hành sẽ tạo một mục để thể hiện tệp đó và lưu trữ thông tin về tệp đã mở đó. Vì vậy, nếu có 100 tệp được mở trong HĐH của bạn thì sẽ có 100 mục trong HĐH (ở đâu đó trong kernel). Các mục này được đại diện bởi các số nguyên như (... 100, 101, 102 ....). Số mục này là mô tả tập tin. Vì vậy, nó chỉ là một số nguyên đại diện duy nhất cho một tệp được mở trong hệ điều hành. Nếu quy trình của bạn mở 10 tệp thì bảng Quy trình của bạn sẽ có 10 mục nhập cho mô tả tệp.

Tương tự như vậy khi bạn mở một ổ cắm mạng, nó cũng được biểu thị bằng một số nguyên và nó được gọi là Bộ mô tả ổ cắm. Tôi hy vọng bạn hiểu.


7
Ngoài ra, đây là lý do tại sao bạn có thể hết các mô tả tệp, nếu bạn mở nhiều tệp cùng một lúc. Điều này sẽ ngăn các hệ thống * nix chạy, vì chúng mở các mô tả thành công cụ /procmọi lúc.
Spencer Rathbun

8
@ErbenMo: Không, nó có thể không giống nhau. Khi bạn mở tệp, hệ điều hành sẽ chỉ định một FD có sẵn và khi bạn đóng nó thì HĐH sẽ giải phóng FD và có thể gán FD đó cho một tệp khác được mở sau đó. Cách hệ điều hành của nó để theo dõi các tệp đã mở và nó không liên quan gì đến một tệp cụ thể.
Tayyab

49
" Vì vậy, nó chỉ là một số nguyên đại diện duy nhất cho một tệp được mở trong hệ điều hành. " Điều này không chính xác. Số nguyên đó đại diện duy nhất cho một tệp được mở trong một quy trình . Ví dụ, mô tả tệp 0 sẽ đại diện cho một tệp đã mở trong một quy trình và một tệp được mở hoàn toàn khác trong quy trình khác.
Keith Thompson

15
@Tayyab: Tôi tin rằng bạn đã nhầm. Bộ mô tả tệp 0, 1 và 2 là đầu vào tiêu chuẩn, đầu ra tiêu chuẩn và lỗi tiêu chuẩn cho mỗi quy trình đang chạy. Một cuộc gọi ban đầu thành công open()sẽ cung cấp cho bạn bộ mô tả tệp 3, ngay cả khi một quá trình đang chạy khác xảy ra có một bộ mô tả tệp 3. Xem định nghĩa POSIX củaopen() : "Hàm open () sẽ trả về một bộ mô tả tệp cho tệp được đặt tên là thấp nhất mô tả tập tin hiện không mở cho quá trình đó . " (nhấn mạnh thêm).
Keith Thompson

17
@KeithThndry: Có bạn đúng. Trên thực tế của nó về mức độ trừu tượng. Trên thực tế, hai bảng được duy trì, trong đó bảng đầu tiên là mỗi quy trình và bảng thứ hai là toàn hệ thống. FD trong bảng mỗi quá trình (tức là fdtable) không phải là hệ thống duy nhất. Tuy nhiên, nó ánh xạ tới bảng v-nút chứa các mục duy nhất trên toàn hệ thống. Vì vậy, khi bạn gọi hàm fopen () và fileno () để kiểm tra bộ mô tả thì bạn có thể nhận được cùng số FD trong 2 quy trình khác nhau vì nó trả về chỉ mục của fdtable là mỗi quy trình. Cảm ơn vì đã mang nó lên!!
Tayyab

116

Bộ mô tả tệp là một thẻ điều khiển mờ được sử dụng trong giao diện giữa không gian người dùng và nhân để xác định tài nguyên tệp / ổ cắm. Do đó, khi bạn sử dụng open()hoặc socket()(gọi hệ thống để giao diện với kernel), bạn sẽ được cung cấp một bộ mô tả tệp, đó là một số nguyên (nó thực sự là một chỉ mục trong cấu trúc u quy trình - nhưng điều đó không quan trọng). Do đó, nếu bạn muốn giao tiếp trực tiếp với các hạt nhân, sử dụng các cuộc gọi hệ thống để read(), write(), close()vv các xử lý bạn sử dụng là một bộ mô tả tập tin.

Có một lớp trừu tượng được phủ lên trên các cuộc gọi hệ thống, đó là stdiogiao diện. Điều này cung cấp nhiều chức năng / tính năng hơn các cuộc gọi hệ thống cơ bản. Đối với giao diện này, tay cầm mờ bạn nhận được là một FILE*, được trả về bởi fopen()cuộc gọi. Có rất nhiều nhiều chức năng sử dụng các stdiogiao diện fprintf(), fscanf(), fclose(), mà đang có để làm cho cuộc sống của bạn dễ dàng hơn. Trong C, stdin, stdout, và stderrFILE*, mà trong UNIX tương ứng bản đồ để mô tả tập tin 0, 12.


6
Cá nhân tôi nghĩ rằng câu trả lời này tốt hơn câu trả lời. Nâng cao.
Tarik

101

Nghe nó từ Miệng Ngựa: APUE (Richard Stevens).
Đối với kernel, tất cả các tệp đang mở được tham chiếu bởi Trình mô tả tệp. Một mô tả tập tin là một số không âm.

Khi chúng ta mở một tệp hiện có hoặc tạo một tệp mới, kernel sẽ trả về một bộ mô tả tệp cho quy trình. Hạt nhân duy trì một bảng của tất cả các mô tả tập tin đang mở, đang được sử dụng. Việc phân bổ các bộ mô tả tệp nói chung là tuần tự và chúng được phân bổ cho tệp dưới dạng bộ mô tả tệp miễn phí tiếp theo từ nhóm bộ mô tả tệp miễn phí. Khi chúng tôi đóng tệp, bộ mô tả tệp sẽ được giải phóng và có sẵn để phân bổ thêm.
Xem hình ảnh này để biết thêm chi tiết:

Hai quá trình

Khi chúng tôi muốn đọc hoặc ghi một tệp, chúng tôi xác định tệp có bộ mô tả tệp được trả về bằng lệnh gọi hàm open () hoặc tạo () và sử dụng nó làm đối số để đọc () hoặc write () .
Theo quy ước, các hệ thống UNIX shell liên kết bộ mô tả tệp 0 với Đầu vào tiêu chuẩn của một quy trình, bộ mô tả tệp 1 với Đầu ra tiêu chuẩn và bộ mô tả tệp 2 với Lỗi tiêu chuẩn .
Bộ mô tả tệp nằm trong khoảng từ 0 đến OPEN_MAX. Giá trị tối đa mô tả tập tin có thể được lấy với ulimit -n. Để biết thêm thông tin, hãy đi qua chương 3 của Sách APUE.


1
Vì 0, 1, 2 được liên kết với "stdin", "stdout" và "stderr" của một quy trình, chúng ta có thể sử dụng các mô tả đó cùng một lúc cho các quy trình khác nhau không?
Tarik

@Tarik: mô tả tập tin là mỗi quá trình. Để xem điều này, tải xuống osquery và thực hiện osqueryi <<< echo '.all process_open_files'trong bash shell.
Ben Creasy

29

Câu trả lời khác thêm công cụ tuyệt vời. Tôi sẽ chỉ thêm 2 xu của tôi.

Theo Wikipedia chúng tôi biết chắc chắn: một mô tả tập tin là một số nguyên không âm. Điều quan trọng nhất tôi nghĩ là thiếu, sẽ là:

Mô tả tập tin được ràng buộc với một ID quá trình.

Chúng tôi biết hầu hết các mô tả tập tin nổi tiếng là 0, 1 và 2. 0 tương ứng với STDIN, 1 đến STDOUTvà 2 đến STDERR.

Nói, lấy các quy trình shell làm ví dụ và làm thế nào để áp dụng nó?

Kiểm tra mã này

#>sleep 1000 &
[12] 14726

Chúng tôi đã tạo một quy trình với id 14726 (PID). Sử dụng lsof -p 14726chúng ta có thể có được những thứ như thế này:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Cột thứ 4 FD và cột TYPE tiếp theo tương ứng với loại Mô tả tệp và loại Mô tả tệp.

Một số giá trị cho FD có thể là:

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

Nhưng bộ mô tả tập tin thực sự nằm dưới:

NUMBER – Represent the actual file descriptor. 

Ký tự sau số tức là "1u", biểu thị chế độ mở tệp. r để đọc, w để viết, u để đọc và viết.

TYPE chỉ định loại tệp. Một số giá trị của TYPE là:

REG – Regular File
DIR – Directory
FIFO – First In First Out

Nhưng tất cả các mô tả tệp là tệp đặc biệt CHR - Ký tự (hoặc tệp thiết bị ký tự)

Bây giờ, chúng ta có thể xác định các file descriptor cho STDIN, STDOUTSTDERRdễ dàng với lsof -p PID, hoặc chúng ta có thể xem cùng nếu chúng ta ls /proc/PID/fd.

Cũng lưu ý rằng bảng mô tả tệp mà kernel theo dõi không giống như bảng tệp hoặc bảng inodes. Đây là riêng biệt, như một số câu trả lời khác giải thích.

bảng fd

Bạn có thể tự hỏi những mô tả tập tin này ở đâu và /dev/pts/6ví dụ những gì được lưu trữ

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Vâng, /dev/pts/6sống hoàn toàn trong ký ức. Đây không phải là các tệp thông thường, nhưng được gọi là các tệp thiết bị ký tự . Bạn có thể kiểm tra điều này với: ls -l /dev/pts/6và họ sẽ bắt đầu với c, trong trường hợp của tôi crw--w----.

Chỉ cần nhớ lại hầu hết Linux như HĐH xác định bảy loại tệp:

  • Tập tin thông thường
  • Thư mục
  • Tập tin thiết bị nhân vật
  • Chặn tập tin thiết bị
  • Ổ cắm tên miền địa phương
  • Các ống được đặt tên (FIFO) và
  • Liên kết tượng trưng

1
Cảm ơn. Quả thực điều quan trọng là chỉ ra rằng nó là trên mỗi quá trình! Nó giúp hình dung mọi thứ tốt hơn.
Nishant

1
Các loại tệp được xác định bởi HĐH, mà bạn đã đề cập trong câu trả lời của bạn, thực sự giúp ích trong việc hiểu các tệp ở cấp độ thấp hơn.
Rohan Bhale

20

Thêm điểm về File Descriptor:

  1. File Descriptors(FD) là các số nguyên không âm (0, 1, 2, ...)được liên kết với các tệp được mở.

  2. 0, 1, 2là tiêu chuẩn FD 's mà tương ứng với STDIN_FILENO, STDOUT_FILENOSTDERR_FILENO(quy định tại unistd.h) mở theo mặc định trên danh nghĩa của vỏ khi chương trình bắt đầu.

  3. FD được phân bổ theo thứ tự tuần tự, có nghĩa là giá trị nguyên chưa được phân bổ thấp nhất có thể.

  4. FD cho một quy trình cụ thể có thể được nhìn thấy /proc/$pid/fd(trên các hệ thống dựa trên Unix).


16

Ngoài các câu trả lời khác, unix coi mọi thứ là một hệ thống tệp. Bàn phím của bạn là một tệp chỉ được đọc từ phối cảnh của kernel. Màn hình là một tập tin chỉ ghi. Tương tự, các thư mục, thiết bị đầu vào-đầu ra, vv cũng được coi là các tệp. Bất cứ khi nào một tệp được mở, hãy nói khi trình điều khiển thiết bị [cho các tệp thiết bị] yêu cầu mở () hoặc một quá trình mở tệp người dùng, hạt nhân cấp phát một bộ mô tả tệp, một số nguyên chỉ định quyền truy cập vào tệp đó để nó chỉ được đọc , chỉ viết, v.v. [để tham khảo: https://en.wikipedia.org/wiki/Everything_is_a_file ]


Bộ mô tả tệp cũng có thể đề cập đến những thứ không tồn tại trong hệ thống tệp, như ống dẫn ẩn danh và ổ cắm mạng.
kbolino

12

Mô tả tệp (FD):

  • Trong Linux / Unix , mọi thứ đều là một tệp. Tệp thông thường, Thư mục và thậm chí Thiết bị là tệp. Mỗi tệp có một số liên quan được gọi là Mô tả tệp (FD).
  • Màn hình của bạn cũng có Bộ mô tả tệp. Khi một chương trình được thực thi, đầu ra được gửi đến Trình mô tả tệp của màn hình và bạn thấy đầu ra chương trình trên màn hình của bạn. Nếu đầu ra được gửi đến Bộ mô tả tệp của máy in, đầu ra chương trình sẽ được in.

    Lỗi chuyển hướng:
    Bất cứ khi nào bạn thực hiện một chương trình / lệnh tại thiết bị đầu cuối, 3 tệp luôn mở
    1. đầu vào tiêu chuẩn
    2. đầu ra tiêu chuẩn
    3. lỗi tiêu chuẩn.

    Những tập tin này luôn có mặt bất cứ khi nào một chương trình được chạy. Như đã giải thích trước một bộ mô tả tệp, được liên kết với mỗi tệp này.
    Tệp                                        Tệp Mô tả
    Đầu vào tiêu chuẩn STDIN 0
    Đầu ra tiêu chuẩn STDOUT 1
    Lỗi tiêu chuẩn STDERR 2

  • Chẳng hạn, trong khi tìm kiếm tệp, người ta thường nhận được quyền từ chối lỗi hoặc một số loại lỗi khác. Những lỗi này có thể được lưu vào một tập tin cụ thể.
    ví dụ 1

$ ls mydir 2> lỗifile.txt

Bộ mô tả tệp cho lỗi tiêu chuẩn là 2.
Nếu không có bất kỳ thư mục nào có tên là mydir thì đầu ra của lệnh sẽ được lưu vào tệp errorfile.txt
Sử dụng "2>", chúng tôi chuyển hướng đầu ra lỗi sang tệp có tên "errorfile. txt "
Như vậy, đầu ra chương trình không bị lộn xộn với lỗi.

Tôi hy vọng bạn có câu trả lời của bạn.


5

Bất kỳ hệ điều hành nào cũng có các tiến trình (p's) đang chạy, giả sử p1, p2, p3 , v.v. Mỗi quá trình thường làm cho việc sử dụng tập tin liên tục.

Mỗi quy trình bao gồm một cây quy trình (hoặc một bảng quy trình, trong một cụm từ khác).

Thông thường, Hệ điều hành đại diện cho mỗi tệp trong mỗi quy trình bằng một số (có nghĩa là, trong mỗi cây / bảng quy trình).

Các tập tin đầu tiên được sử dụng trong quá trình này là file0 , thứ hai là file1 , thứ ba là file2 , và vân vân.

Bất kỳ số nào là một mô tả tập tin.

Mô tả tệp thường là số nguyên (0, 1, 2 chứ không phải 0,5, 1,5, 2,5).

Do chúng ta thường mô tả các quy trình là "bảng quy trình" và do các bảng có hàng (mục), chúng ta có thể nói rằng ô mô tả tệp trong mỗi mục, sử dụng để thể hiện toàn bộ mục.

Theo cách tương tự, khi bạn mở một ổ cắm mạng, nó có một bộ mô tả ổ cắm.

Trong một số hệ điều hành, bạn có thể dùng hết phần mô tả tệp, nhưng trường hợp như vậy là cực kỳ hiếm và người dùng máy tính trung bình không nên lo lắng về điều đó.

Các mô tả tệp có thể là toàn cục (quy trình A bắt đầu bằng 0 và kết thúc bằng 1; Quá trình B bắt đầu bằng 2 và kết thúc bằng 3), v.v., theo như tôi biết, thông thường trong các hệ điều hành hiện đại, tệp các mô tả không phải là toàn cục và thực sự là quy trình cụ thể (quy trình A bắt đầu bằng nói 0 và kết thúc bằng 5, trong khi quy trình B bắt đầu bằng 0 và kết thúc bằng 10).


Đọc thêm về FD's trong Linux tại đây: unix.stackexchange.com/questions3538022/iêu

1
câu trả lời tuyệt vời :)
humble_wolf

5

Mô tả tập tin

  • Để Kernel tất cả các tệp đang mở được tham chiếu bởi các mô tả tệp.
  • Một mô tả tập tin là một số nguyên không âm.
  • Khi chúng ta mở một tệp hiện có hoặc tạo một tệp mới, kernel sẽ trả về một bộ mô tả tệp cho một tiến trình.
  • Khi chúng tôi muốn đọc hoặc ghi trên một tệp, chúng tôi xác định tệp có mô tả tệp được trả về bằng cách mở hoặc tạo, làm đối số để đọc hoặc ghi.
  • Mỗi quy trình UNIX có 20 mô tả tệp và xử lý, được đánh số từ 0 đến 19 nhưng nó được mở rộng đến 63 bởi nhiều hệ thống.
  • Ba cái đầu tiên đã được mở khi quá trình bắt đầu 0: Đầu vào tiêu chuẩn 1: Đầu ra tiêu chuẩn 2: Đầu ra lỗi tiêu chuẩn
  • Khi tiến trình cha tạo ra một tiến trình, tiến trình con sẽ kế thừa các mô tả tệp của cha mẹ

1

Ngoài ra trên tất cả các câu trả lời đơn giản hóa.
Nếu bạn đang làm việc với các tệp trong tập lệnh bash, tốt hơn là sử dụng bộ mô tả tệp.
Ví dụ: -
Bạn muốn đọc và ghi từ / vào tệp "test.txt".
Sử dụng mô tả tập tin như hiển thị dưới đây

FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor

-5

Mô tả tập tin là mô tả cho một tập tin. Họ cung cấp liên kết đến một tập tin. Với sự giúp đỡ của họ, chúng tôi có thể đọc, viết và mở một tập tin.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.