Việc mở một tập tin thực sự làm gì?


266

Trong tất cả các ngôn ngữ lập trình (mà tôi sử dụng ít nhất), bạn phải mở một tệp trước khi bạn có thể đọc hoặc ghi vào nó.

Nhưng hoạt động mở này thực sự làm gì?

Các trang hướng dẫn cho các chức năng thông thường không thực sự cho bạn biết bất cứ điều gì ngoài nó 'mở tệp để đọc / ghi':

http://www.cplusplus.com/reference/cstdio/fopen/

https://docs.python.org/3/l Library / fiances.html # open

Rõ ràng, thông qua việc sử dụng chức năng, bạn có thể biết nó liên quan đến việc tạo ra một loại đối tượng nào đó tạo điều kiện truy cập một tệp.

Một cách khác để đặt điều này là, nếu tôi thực hiện một openchức năng, nó cần phải làm gì trên Linux?


13
Chỉnh sửa câu hỏi này để tập trung vào Cvà Linux; vì những gì Linux và Windows làm khác nhau. Nếu không, nó hơi quá rộng. Ngoài ra, bất kỳ ngôn ngữ cấp cao hơn nào cũng sẽ gọi API C cho hệ thống hoặc biên dịch xuống C để thực thi, do đó, việc để lại ở cấp độ "C" sẽ đặt nó vào Mẫu số chung nhỏ nhất.
George Stocker

1
Chưa kể rằng không phải tất cả các ngôn ngữ lập trình đều có cơ sở này, hoặc nó là một cơ sở phụ thuộc nhiều vào môi trường. Tất nhiên, ngày nay hiếm khi được thừa nhận, nhưng cho đến ngày nay, việc xử lý tệp là một phần hoàn toàn tùy chọn của ANSI Forth và thậm chí không có mặt trong một số triển khai trong quá khứ.

Câu trả lời:


184

Trong hầu hết mọi ngôn ngữ cấp cao, chức năng mở tệp là một trình bao bọc xung quanh lệnh gọi hệ thống kernel tương ứng. Nó cũng có thể làm những thứ ưa thích khác, nhưng trong các hệ điều hành hiện đại, việc mở tệp phải luôn đi qua kernel.

Đây là lý do tại sao các đối số của fopenhàm thư viện hoặc Python opengần giống với các đối số của lệnh open(2)gọi hệ thống.

Ngoài việc mở tệp, các hàm này thường thiết lập bộ đệm do đó sẽ được sử dụng với các hoạt động đọc / ghi. Mục đích của bộ đệm này là để đảm bảo rằng bất cứ khi nào bạn muốn đọc N byte, cuộc gọi thư viện tương ứng sẽ trả về N byte, bất kể các cuộc gọi đến các cuộc gọi hệ thống cơ bản có trả về ít hơn hay không.

Tôi không thực sự quan tâm đến việc thực hiện chức năng của riêng tôi; chỉ cần hiểu những gì đang xảy ra ... 'ngoài ngôn ngữ' nếu bạn muốn.

Trong các hệ điều hành giống như Unix, một cuộc gọi thành công đến open trả về "bộ mô tả tệp" chỉ là một số nguyên trong ngữ cảnh của quy trình người dùng. Do đó, bộ mô tả này được chuyển đến bất kỳ cuộc gọi nào tương tác với tệp đã mở và sau khi gọi closenó, bộ mô tả trở nên không hợp lệ.

Điều quan trọng cần lưu ý là lệnh gọi openhành động giống như một điểm xác nhận mà tại đó các kiểm tra khác nhau được thực hiện. Nếu không phải tất cả các điều kiện đều được đáp ứng, cuộc gọi thất bại bằng cách quay lại -1thay vì mô tả và loại lỗi được chỉ định trong errno. Các kiểm tra thiết yếu là:

  • Liệu các tập tin tồn tại;
  • Liệu quy trình gọi có được đặc quyền mở tệp này trong chế độ được chỉ định hay không. Điều này được xác định bằng cách khớp các quyền của tệp, ID chủ sở hữu và ID nhóm với ID tương ứng của quy trình gọi.

Trong ngữ cảnh của kernel, phải có một số loại ánh xạ giữa các bộ mô tả tệp của quy trình và các tệp được mở vật lý. Cấu trúc dữ liệu nội bộ được ánh xạ tới bộ mô tả có thể chứa một bộ đệm khác liên quan đến các thiết bị dựa trên khối hoặc một con trỏ bên trong trỏ đến vị trí đọc / ghi hiện tại.


2
Điều đáng chú ý là trong các HĐH giống Unix, các bộ mô tả tệp cấu trúc trong nhân được ánh xạ tới, được gọi là "mô tả tệp mở". Vì vậy, các FD quá trình được ánh xạ tới kernel OFD. Điều này rất quan trọng để hiểu tài liệu. Ví dụ, xem man dup2và kiểm tra sự tinh tế giữa một bộ mô tả tệp đang mở (đó là một FD xảy ra để mở) và một mô tả tệp mở (OFD).
Rodrigo

1
Có, quyền được kiểm tra tại thời điểm mở. Bạn có thể đi và đọc nguồn để triển khai "mở" của kernel: lxr.free-electrons.com/source/fs/open.c mặc dù nó ủy thác hầu hết công việc cho trình điều khiển hệ thống tệp cụ thể.
pjc50

1
(trên các hệ thống ext2, điều này sẽ liên quan đến việc đọc các mục nhập thư mục để xác định inode nào có siêu dữ liệu, sau đó tải inode đó vào bộ đệm inode. khi bạn mở tệp)
pjc50

1
Lưu ý rằng các kiểm tra trên tệp mở - rằng tệp tồn tại, mà bạn có quyền - trong thực tế, là không đủ. Các tập tin có thể biến mất, hoặc quyền của nó có thể thay đổi, dưới chân của bạn. Một số hệ thống tệp cố gắng ngăn chặn điều này, nhưng miễn là HĐH của bạn hỗ trợ lưu trữ mạng thì không thể ngăn chặn được (HĐH có thể "hoảng loạn" nếu hệ thống tệp cục bộ hoạt động sai và hợp lý: một điều đó không xảy ra khi chia sẻ mạng không một hệ điều hành khả thi). Những kiểm tra đó cũng được thực hiện khi mở tệp, nhưng cũng phải được thực hiện ở tất cả các quyền truy cập tệp khác.
Yakk - Adam Nevraumont

2
Đừng quên đánh giá và / hoặc tạo ra các khóa. Chúng có thể được chia sẻ hoặc độc quyền và có thể ảnh hưởng đến toàn bộ tệp hoặc chỉ một phần của tệp.
Thinkeye

83

Tôi khuyên bạn nên xem hướng dẫn này thông qua một phiên bản đơn giản của open()cuộc gọi hệ thống . Nó sử dụng đoạn mã sau, đại diện cho những gì xảy ra đằng sau hậu trường khi bạn mở tệp.

0  int sys_open(const char *filename, int flags, int mode) {
1      char *tmp = getname(filename);
2      int fd = get_unused_fd();
3      struct file *f = filp_open(tmp, flags, mode);
4      fd_install(fd, f);
5      putname(tmp);
6      return fd;
7  }

Tóm lại, đây là những gì mã đó làm, từng dòng:

  1. Phân bổ một khối bộ nhớ do kernel kiểm soát và sao chép tên tệp vào nó từ bộ nhớ do người dùng kiểm soát.
  2. Chọn một bộ mô tả tệp không được sử dụng, mà bạn có thể nghĩ là một chỉ số nguyên vào một danh sách có thể phát triển của các tệp hiện đang mở. Mỗi tiến trình có một danh sách như vậy, mặc dù nó được duy trì bởi kernel; mã của bạn không thể truy cập trực tiếp. Một mục trong danh sách chứa bất kỳ thông tin nào mà hệ thống tập tin cơ bản sẽ sử dụng để kéo byte ra khỏi đĩa, chẳng hạn như số inode, quyền xử lý, cờ mở, v.v.
  3. Các filp_openchức năng có thực hiện

    struct file *filp_open(const char *filename, int flags, int mode) {
            struct nameidata nd;
            open_namei(filename, flags, mode, &nd);
            return dentry_open(nd.dentry, nd.mnt, flags);
    }

    trong đó có hai điều:

    1. Sử dụng hệ thống tệp để tra cứu inode (hay nói chung hơn, bất kỳ loại định danh nội bộ nào mà hệ thống tệp sử dụng) tương ứng với tên tệp hoặc đường dẫn được truyền vào.
    2. Tạo một struct filethông tin cần thiết về inode và trả lại nó. Cấu trúc này trở thành mục trong danh sách các tệp đang mở mà tôi đã đề cập trước đó.
  4. Lưu trữ ("cài đặt") cấu trúc được trả về vào danh sách các tệp đang mở của quy trình.

  5. Giải phóng khối được cấp phát của bộ nhớ điều khiển kernel.
  6. Trả lại bộ mô tả tập tin, mà sau đó có thể được thông qua với chức năng hoạt động tập tin như read(), write(), và close(). Mỗi trong số này sẽ trao quyền điều khiển cho kernel, có thể sử dụng bộ mô tả tệp để tra cứu con trỏ tệp tương ứng trong danh sách của tiến trình và sử dụng thông tin trong con trỏ tệp đó để thực sự đọc, ghi hoặc đóng.

Nếu bạn cảm thấy tham vọng, bạn có thể so sánh ví dụ đơn giản này với việc thực hiện open()lệnh gọi hệ thống trong nhân Linux, một hàm được gọi do_sys_open(). Bạn không nên gặp khó khăn trong việc tìm kiếm sự tương đồng.


Tất nhiên, đây chỉ là "lớp trên cùng" của những gì xảy ra khi bạn gọi open()- hay chính xác hơn, đó là đoạn mã hạt nhân cấp cao nhất được gọi trong quá trình mở tệp. Một ngôn ngữ lập trình cấp cao có thể thêm các lớp bổ sung lên trên này. Có rất nhiều thứ diễn ra ở cấp thấp hơn. (Cảm ơn Ruslanpjc50 đã giải thích.) Roughly, từ trên xuống dưới:

  • open_namei()dentry_open()gọi mã hệ thống tập tin, cũng là một phần của kernel, để truy cập siêu dữ liệu và nội dung cho các tệp và thư mục. Hệ thống tệp đọc các byte thô từ đĩa và diễn giải các mẫu byte đó dưới dạng cây của các tệp và thư mục.
  • Hệ thống tập tin sử dụng lớp thiết bị khối , một phần của hạt nhân, để lấy các byte thô đó từ ổ đĩa. (Sự thật thú vị: Linux cho phép bạn truy cập dữ liệu thô từ lớp thiết bị khối bằng cách sử dụng /dev/sdavà tương tự.)
  • Lớp thiết bị khối gọi trình điều khiển thiết bị lưu trữ, cũng là mã hạt nhân, để dịch từ một lệnh trung bình như "đọc sector X" sang các lệnh đầu vào / đầu ra riêng lẻ trong mã máy. Có một số loại trình điều khiển thiết bị lưu trữ, bao gồm IDE , (S) ATA , SCSI , Firewire , v.v., tương ứng với các tiêu chuẩn truyền thông khác nhau mà ổ đĩa có thể sử dụng. (Lưu ý rằng việc đặt tên là một mớ hỗn độn.)
  • Các hướng dẫn I / O sử dụng các khả năng tích hợp của chip xử lý và bộ điều khiển bo mạch chủ để gửi và nhận tín hiệu điện trên dây đi đến ổ đĩa vật lý. Đây là phần cứng, không phải phần mềm.
  • Ở đầu dây bên kia, phần sụn của đĩa (mã điều khiển nhúng) diễn giải các tín hiệu điện để quay đĩa và di chuyển đầu (HDD) hoặc đọc một tế bào ROM flash (SSD) hoặc bất cứ điều gì cần thiết để truy cập dữ liệu trên loại thiết bị lưu trữ đó.

Điều này cũng có thể không chính xác do bộ nhớ đệm . :-P Nghiêm túc mà nói, có nhiều chi tiết tôi đã bỏ qua - một người (không phải tôi) có thể viết nhiều cuốn sách mô tả toàn bộ quá trình này hoạt động như thế nào. Nhưng điều đó sẽ cho bạn một ý tưởng.


67

Bất kỳ hệ thống tập tin hoặc hệ điều hành nào bạn muốn nói về tôi đều ổn. Đẹp!


Trên Phổ ZX, khởi tạo LOADlệnh sẽ đưa hệ thống vào một vòng lặp chặt chẽ, đọc dòng Âm thanh.

Bắt đầu dữ liệu được biểu thị bằng một âm không đổi và sau đó một chuỗi các xung dài / ngắn theo sau, trong đó một xung ngắn dành cho nhị phân 0và một xung dài hơn cho nhị phân 1( https://en.wikipedia.org/ wiki / ZX_Spectrum_software ). Vòng lặp tải chặt chẽ tập hợp các bit cho đến khi nó lấp đầy một byte (8 bit), lưu trữ điều này vào bộ nhớ, tăng con trỏ bộ nhớ, sau đó lặp lại để quét thêm bit.

Thông thường, điều đầu tiên mà trình tải sẽ đọc là một tiêu đề định dạng ngắn, cố định , cho biết ít nhất số byte cần mong đợi và có thể là thông tin bổ sung như tên tệp, loại tệp và địa chỉ tải. Sau khi đọc tiêu đề ngắn này, chương trình có thể quyết định có tiếp tục tải phần lớn dữ liệu chính hay thoát khỏi thói quen tải và hiển thị thông báo phù hợp cho người dùng.

Có thể nhận ra trạng thái Cuối tệp bằng cách nhận bao nhiêu byte như mong đợi (có thể là số byte cố định, được gắn cứng trong phần mềm hoặc số biến như được chỉ định trong tiêu đề). Một lỗi đã được đưa ra nếu vòng lặp tải không nhận được xung trong dải tần số dự kiến ​​trong một khoảng thời gian nhất định.


Một chút nền tảng về câu trả lời này

Quy trình được mô tả tải dữ liệu từ một băng âm thanh thông thường - do đó cần phải quét Audio In (nó được kết nối với một phích cắm tiêu chuẩn để ghi băng). Một LOADlệnh về mặt kỹ thuật giống như openmột tệp - nhưng nó thực sự gắn liền với việc thực sự tải tệp. Điều này là do máy ghi âm không được điều khiển bởi máy tính và bạn không thể (thành công) mở tệp nhưng không tải được.

"Vòng lặp chặt chẽ" được đề cập vì (1) CPU, Z80-A (nếu bộ nhớ phục vụ), rất chậm: 3,5 MHz và (2) Spectrum không có xung nhịp bên trong! Điều đó có nghĩa là nó phải giữ chính xác số lượng trạng thái T (thời gian hướng dẫn) cho mỗi trạng thái. Độc thân. chỉ dẫn. bên trong vòng lặp đó, chỉ để duy trì thời gian tiếng bíp chính xác.
May mắn thay, tốc độ CPU thấp đó có lợi thế khác biệt là bạn có thể tính được số chu kỳ trên một tờ giấy, và do đó thời gian thực mà chúng sẽ mất.


10
@BillWoodger: vâng. Nhưng đó là một câu hỏi công bằng (ý tôi là của bạn). Tôi đã bỏ phiếu để đóng là "quá rộng" và câu trả lời của tôi là để minh họa cho câu hỏi thực sự rộng đến mức nào.
usr2564301

8
Tôi nghĩ rằng bạn đang mở rộng câu trả lời một chút quá nhiều. ZX Spectrum có lệnh OPEN và điều đó hoàn toàn khác với LOAD. Và khó hiểu hơn.
Rodrigo

3
Tôi cũng không đồng ý về việc đóng câu hỏi, nhưng tôi thực sự thích câu trả lời của bạn.
Enzo Ferber

23
Mặc dù tôi đã chỉnh sửa câu hỏi của mình để hạn chế hệ điều hành linux / windows trong nỗ lực duy trì mở, nhưng câu trả lời này hoàn toàn hợp lệ và hữu ích. Như đã nêu trong câu hỏi của tôi, tôi không tìm cách để thực hiện một cái gì đó hoặc để người khác làm công việc của tôi, tôi đang tìm cách để học hỏi. Để học, bạn phải đặt câu hỏi 'lớn'. Nếu chúng tôi liên tục đóng các câu hỏi về SO vì 'quá rộng', nó có nguy cơ trở thành nơi khiến mọi người viết mã cho bạn mà không đưa ra bất kỳ lời giải thích nào về điều gì, ở đâu hoặc tại sao. Tôi thà giữ nó như một nơi tôi có thể đến để học hỏi.
jramm

14
Câu trả lời này dường như chứng minh rằng cách giải thích của bạn về câu hỏi quá rộng, hơn là bản thân câu hỏi quá rộng.
jwg

17

Nó phụ thuộc vào hệ điều hành chính xác những gì xảy ra khi bạn mở một tập tin. Dưới đây tôi mô tả những gì xảy ra trong Linux vì nó cho bạn biết điều gì sẽ xảy ra khi bạn mở một tệp và bạn có thể kiểm tra mã nguồn nếu bạn quan tâm đến chi tiết hơn. Tôi không bao gồm các quyền vì nó sẽ làm cho câu trả lời này quá dài.

Trong Linux, mọi tệp được nhận dạng bởi một cấu trúc gọi là inode. Mỗi cấu trúc có một số duy nhất và mỗi tệp chỉ nhận được một số inode. Cấu trúc này lưu trữ dữ liệu meta cho một tệp, ví dụ kích thước tệp, quyền tệp, dấu thời gian và con trỏ tới các khối đĩa, tuy nhiên, không phải là tên tệp thực tế. Mỗi tệp (và thư mục) chứa một mục nhập tên tệp và số inode để tra cứu. Khi bạn mở một tệp, giả sử bạn có các quyền liên quan, một bộ mô tả tệp được tạo bằng cách sử dụng số inode duy nhất được liên kết với tên tệp. Vì nhiều quy trình / ứng dụng có thể trỏ đến cùng một tệp, inode có trường liên kết duy trì tổng số liên kết đến tệp. Nếu một tệp có trong một thư mục, số lượng liên kết của nó là một, nếu nó có liên kết cứng thì số liên kết của nó sẽ là hai và nếu một tệp được mở bởi một quy trình, số lượng liên kết sẽ tăng lên 1.


6
Điều này có liên quan gì đến câu hỏi thực tế?
Bill Woodger

1
Nó mô tả những gì xảy ra ở mức thấp khi bạn mở một tệp trong Linux. Tôi đồng ý câu hỏi khá rộng, vì vậy đây có thể không phải là câu trả lời mà jramm đang tìm kiếm.
Alex

1
Vì vậy, một lần nữa, không kiểm tra cho phép?
Bill Woodger

11

Sổ sách kế toán, chủ yếu. Điều này bao gồm các kiểm tra khác nhau như "Tập tin có tồn tại không?" và "Tôi có quyền mở tệp này để viết không?".

Nhưng đó là tất cả các công cụ hạt nhân - trừ khi bạn đang triển khai hệ điều hành đồ chơi của riêng mình, sẽ không có nhiều điều để tìm hiểu (nếu bạn vui vẻ - đó là một trải nghiệm học tập tuyệt vời). Tất nhiên, bạn vẫn nên tìm hiểu tất cả các mã lỗi có thể nhận được khi mở tệp, để bạn có thể xử lý chúng đúng cách - nhưng đó thường là những tóm tắt nhỏ.

Phần quan trọng nhất ở cấp mã là nó cung cấp cho bạn một tệp xử lý tệp đang mở, mà bạn sử dụng cho tất cả các hoạt động khác mà bạn thực hiện với một tệp. Bạn không thể sử dụng tên tệp thay vì xử lý tùy ý này? Chà, chắc chắn - nhưng sử dụng tay cầm mang đến cho bạn một số lợi thế:

  • Hệ thống có thể theo dõi tất cả các tệp hiện đang mở và ngăn không cho chúng bị xóa (ví dụ).
  • Các hệ điều hành hiện đại được xây dựng xung quanh tay cầm - có vô số điều hữu ích bạn có thể làm với tay cầm và tất cả các loại tay cầm khác nhau hoạt động gần như giống hệt nhau. Ví dụ: khi thao tác I / O không đồng bộ hoàn thành trên tay cầm tệp Windows, tay cầm được báo hiệu - điều này cho phép bạn chặn trên tay cầm cho đến khi nó báo hiệu hoặc hoàn thành thao tác hoàn toàn không đồng bộ. Chờ đợi trên một tệp xử lý chính xác giống như chờ trên một xử lý luồng (được báo hiệu, ví dụ như khi luồng kết thúc), một xử lý (một lần nữa, được báo hiệu khi quá trình kết thúc) hoặc một ổ cắm (khi một số hoạt động không đồng bộ hoàn thành). Cũng quan trọng, các tay cầm được sở hữu bởi các quy trình tương ứng của chúng, vì vậy khi một quá trình bị chấm dứt bất ngờ (hoặc ứng dụng được viết kém), HĐH sẽ biết những gì xử lý nó có thể giải phóng.
  • Hầu hết các hoạt động là vị trí - bạn readtừ vị trí cuối cùng trong tệp của bạn. Bằng cách sử dụng tay cầm để xác định một "mở" cụ thể của một tệp, bạn có thể có nhiều tay cầm đồng thời cho cùng một tệp, mỗi lần đọc từ vị trí của chúng. Theo một cách nào đó, tay cầm hoạt động như một cửa sổ có thể di chuyển vào tệp (và cách phát hành các yêu cầu I / O không đồng bộ, rất tiện dụng).
  • Cụm tay lái nhiều nhỏ hơn tên tập tin. Một tay cầm thường có kích thước của một con trỏ, thường là 4 hoặc 8 byte. Mặt khác, tên tệp có thể có hàng trăm byte.
  • Xử lý cho phép HĐH di chuyển tệp, mặc dù các ứng dụng đã mở - xử lý vẫn hợp lệ và nó vẫn trỏ đến cùng một tệp, mặc dù tên tệp đã thay đổi.

Ngoài ra còn có một số thủ thuật khác mà bạn có thể thực hiện (ví dụ: chia sẻ xử lý giữa các quy trình để có kênh liên lạc mà không sử dụng tệp vật lý; trên các hệ thống unix, các tệp cũng được sử dụng cho các thiết bị và các kênh ảo khác, vì vậy điều này không thực sự cần thiết ), nhưng chúng không thực sự gắn liền với openhoạt động, vì vậy tôi sẽ không đi sâu vào vấn đề đó.


7

Tại cốt lõi của nó khi mở để đọc không có gì lạ mắt thực sự cần phải xảy ra. Tất cả những gì nó cần làm là kiểm tra tệp tồn tại và ứng dụng có đủ đặc quyền để đọc nó và tạo một điều khiển để bạn có thể đưa ra các lệnh đọc cho tệp.

Đó là trên các lệnh mà đọc thực tế sẽ được gửi đi.

HĐH thường sẽ bắt đầu đọc bằng cách bắt đầu thao tác đọc để điền vào bộ đệm liên quan đến tay cầm. Sau đó, khi bạn thực sự đọc nó, nó có thể trả về nội dung của bộ đệm ngay lập tức sau đó cần phải đợi trên đĩa IO.

Để mở một tệp mới để ghi, HĐH sẽ cần thêm một mục trong thư mục cho tệp mới (hiện đang trống). Và một lần nữa một tay cầm được tạo ra để bạn có thể đưa ra các lệnh ghi.


5

Về cơ bản, một lệnh gọi để mở cần tìm tệp, và sau đó ghi lại bất cứ thứ gì nó cần để các thao tác I / O sau này có thể tìm lại được. Điều đó khá mơ hồ, nhưng nó sẽ đúng trên tất cả các hệ điều hành mà tôi có thể nghĩ ngay lập tức. Các chi tiết cụ thể khác nhau từ nền tảng để nền tảng. Nhiều câu trả lời đã có ở đây nói về các hệ điều hành máy tính để bàn hiện đại. Tôi đã thực hiện một chương trình nhỏ về CP / M, vì vậy tôi sẽ cung cấp kiến ​​thức về cách thức hoạt động của nó trên CP / M (MS-DOS có thể hoạt động theo cùng một cách, nhưng vì lý do bảo mật, ngày nay nó không được thực hiện như thế này ).

Trên CP / M, bạn có một thứ gọi là FCB (như bạn đã đề cập đến C, bạn có thể gọi nó là một cấu trúc; nó thực sự là một vùng liền kề 35 byte trong RAM chứa các trường khác nhau). FCB có các trường để ghi tên tệp và số nguyên (4 bit) xác định ổ đĩa. Sau đó, khi bạn gọi Open File của kernel, bạn chuyển một con trỏ tới cấu trúc này bằng cách đặt nó vào một trong các thanh ghi của CPU. Một thời gian sau, hệ điều hành trở lại với cấu trúc hơi thay đổi. Bất cứ I / O nào bạn làm với tệp này, bạn đều chuyển một con trỏ tới cấu trúc này cho lệnh gọi hệ thống.

CP / M làm gì với FCB này? Nó bảo lưu các trường nhất định để sử dụng riêng và sử dụng các trường này để theo dõi tệp, vì vậy bạn không nên chạm vào chúng từ bên trong chương trình của mình. Thao tác mở tệp tìm kiếm thông qua bảng ở đầu đĩa để tìm tệp có cùng tên với FCB (ký tự đại diện '?' Phù hợp với bất kỳ ký tự nào). Nếu nó tìm thấy một tệp, nó sao chép một số thông tin vào FCB, bao gồm (các) vị trí thực của tệp trên đĩa, để các cuộc gọi I / O tiếp theo cuối cùng gọi BIOS có thể chuyển các vị trí này đến trình điều khiển đĩa. Ở cấp độ này, chi tiết cụ thể khác nhau.


-7

Nói một cách đơn giản, khi bạn mở một tệp, bạn thực sự yêu cầu hệ điều hành tải tệp mong muốn (sao chép nội dung của tệp) từ bộ lưu trữ thứ cấp sang ram để xử lý. Và lý do đằng sau điều này (Tải một tệp) là vì bạn không thể xử lý tệp trực tiếp từ Đĩa cứng vì tốc độ cực chậm so với Ram.

Lệnh mở sẽ tạo ra một cuộc gọi hệ thống lần lượt sao chép nội dung của tệp từ bộ lưu trữ thứ cấp (Đĩa cứng) sang Bộ lưu trữ chính (Ram).

Và chúng tôi 'Đóng' một tệp vì nội dung đã sửa đổi của tệp phải được phản ánh thành tệp gốc nằm trong đĩa cứng. :)

Mong rằng sẽ giúp.

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.