[Powered by Google Translate] [File I / O] [Jason Hirschhorn, Đại học Harvard] [Đây là CS50, CS50.TV] Khi chúng ta nghĩ về một tập tin, những gì đến với tâm là một tài liệu Microsoft Word, một hình ảnh JPEG, hoặc bài hát MP3, và chúng ta tương tác với nhau của các loại tập tin theo nhiều cách khác nhau. Ví dụ, trong một tài liệu Word, chúng tôi thêm văn bản trong khi với một hình ảnh JPEG, chúng tôi có thể cắt ra các cạnh hoặc tút lại màu sắc. Tuy nhiên, dưới mui xe tất cả các tập tin trong máy tính của chúng tôi là không có gì hơn nữa hơn một chuỗi dài các số không và những người thân. Nó thuộc vào ứng dụng cụ thể tương tác với các tập tin để quyết định làm thế nào để xử lý chuỗi dài này và trình bày nó cho người dùng. Trên một bàn tay, một tài liệu có thể nhìn vào chỉ một byte, hoặc 8 số không và những người thân, và hiển thị một ký tự ASCII trên màn hình. Mặt khác, một hình ảnh bitmap có thể nhìn vào 3 byte, hoặc 24 số không và những người thân, và giải thích cho họ là 3 số thập lục phân đại diện cho các giá trị cho màu đỏ, xanh lá cây, và màu xanh trong một pixel của một hình ảnh. Dù họ có thể trông giống như trên màn hình của bạn, tại cốt lõi của họ, tập tin này là không có gì nhiều hơn một chuỗi các số không và những người thân. Vì vậy, hãy nhảy vào và xem xét làm thế nào chúng ta thực sự thao tác các số không và những người thân khi nói đến văn bản và đọc từ một tập tin. Tôi sẽ bắt đầu bằng cách phá vỡ nó xuống thành một quá trình 3-phần đơn giản. Tiếp theo, tôi sẽ nhảy vào hai ví dụ mã chứng minh những ba phần. Cuối cùng, tôi sẽ xem xét quá trình và một số chi tiết quan trọng nhất. Như với bất kỳ tập tin mà ngồi trên máy tính để bàn của bạn, Điều đầu tiên cần làm là để mở nó. Trong C, chúng tôi làm điều này bằng cách tuyên bố một con trỏ đến một cấu trúc được xác định trước đại diện cho một tập tin trên đĩa. Trong cuộc gọi chức năng này, chúng tôi cũng quyết định xem chúng ta muốn viết hoặc đọc từ tập tin. Tiếp theo, chúng tôi đọc và viết thực tế. Có một số chức năng chuyên biệt, chúng tôi có thể sử dụng trong phần này, và gần như tất cả trong số họ bắt đầu với F với doanh nghiệp, đó là viết tắt cho tập tin. Cuối cùng, giống như dấu X đỏ nhỏ ở góc trên cùng của các tập tin mở trên máy tính của bạn, chúng tôi đóng tập tin với một cuộc gọi chức năng cuối cùng. Bây giờ chúng ta có một ý tưởng chung của những gì chúng ta sẽ làm, chúng ta hãy đi sâu vào các mã. Trong thư mục này, chúng tôi có hai C tập tin và các tập tin thực thi tương ứng của họ. Chương trình máy đánh chữ mất một đối số dòng lệnh, tên tài liệu, chúng tôi muốn tạo ra. Trong trường hợp này, chúng ta sẽ gọi nó doc.txt. Hãy chạy chương trình và nhập một vài dòng. Hi. Tên tôi là Jason. Cuối cùng, chúng tôi sẽ gõ "bỏ thuốc lá." Nếu bây giờ chúng ta liệt kê tất cả các file trong thư mục này, chúng ta thấy rằng một tài liệu mới tồn tại được gọi là doc.txt. Đó là tập tin chương trình này chỉ tạo ra. Và tất nhiên, nó quá là không có gì nhiều hơn một chuỗi dài các số không và những người thân. Nếu chúng ta mở tập tin này mới, chúng ta thấy 3 dòng mã chúng tôi đã nhập vào chương trình của chúng tôi - Hi. May tên là Jason. Nhưng những gì đang thực sự xảy ra khi typewriter.c chạy? Dòng đầu tiên quan tâm cho chúng ta là dòng 24. Trong đường dây này, chúng ta khai báo con trỏ tập tin của chúng tôi. Chức năng trả về con trỏ, fopen, có hai đối số. Đầu tiên là tên tập tin bao gồm cả phần mở rộng tập tin nếu thích hợp. Nhớ lại rằng một phần mở rộng tập tin không ảnh hưởng đến các tập tin ở mức thấp nhất. Chúng tôi luôn đối phó với một chuỗi dài các số không và những người thân. Nhưng nó có ảnh hưởng như thế nào các tập tin được giải thích và những ứng dụng được sử dụng để mở chúng. Đối số thứ hai để fopen là một lá thư duy nhất là viết tắt của những gì chúng tôi dự định làm gì sau khi chúng tôi mở tập tin. Có ba lựa chọn cho lập luận này - W, R, và A. Chúng tôi đã chọn w trong trường hợp này bởi vì chúng tôi muốn ghi vào tập tin. R, như bạn có thể đoán, là để đọc tập tin. Và một là để phụ thêm vào tập tin. Trong khi cả hai w và có thể được sử dụng để ghi vào tập tin, w sẽ bắt đầu viết từ đầu của tập tin và có khả năng ghi đè lên bất kỳ dữ liệu đã được lưu trữ trước đó. Theo mặc định, tập tin mở, nếu nó không tồn tại, được tạo ra trong thư mục làm việc hiện tại của chúng tôi. Tuy nhiên, nếu chúng ta muốn truy cập hoặc tạo ra một tập tin trong một vị trí khác, trong số đầu tiên của fopen, chúng tôi có thể chỉ định một đường dẫn tập tin thêm vào tên file. Trong khi phần đầu tiên của quá trình này là chỉ có một dòng mã dài, nó luôn luôn là tốt thực hành để bao gồm một tập hợp các đường mà kiểm tra để đảm bảo rằng tập tin đã thành công đã mở hoặc tạo ra. Nếu fopen trả về null, chúng tôi sẽ không muốn giả mạo trước với chương trình của chúng tôi, và điều này có thể xảy ra khi hệ điều hành ra khỏi bộ nhớ hoặc nếu chúng tôi cố gắng để mở một tập tin trong một thư mục mà chúng tôi đã không có sự cho phép thích hợp. Phần hai của quá trình này diễn ra trong vòng lặp trong khi của máy đánh chữ. Chúng tôi sử dụng một chức năng thư viện CS50 để có được đầu vào từ người sử dụng, và giả sử họ không muốn để thoát khỏi chương trình, chúng tôi sử dụng fputs chức năng dùng chuỗi và viết nó vào tập tin. fputs là chỉ là một trong nhiều chức năng chúng ta có thể sử dụng để ghi vào tập tin. Những người khác bao gồm fwrite, fputc, và thậm chí fprintf. Bất kể chức năng cụ thể, chúng tôi kết thúc bằng cách sử dụng, mặc dù, tất cả đều cần phải biết, thông qua các lập luận của họ, ít nhất hai thứ - những gì cần phải được bằng văn bản và nơi nó cần phải được ghi vào. Trong trường hợp của chúng tôi, đầu vào là chuỗi cần phải được viết và fp là con trỏ hướng dẫn chúng ta đến nơi mà chúng ta đang viết. Trong chương trình này, phần hai của quá trình này là khá đơn giản. Chúng tôi chỉ đơn giản là một chuỗi từ người sử dụng và thêm nó trực tiếp vào tập tin của chúng tôi với rất ít-to-đầu vào hoặc không có xác nhận kiểm tra an ninh. Thường, tuy nhiên, phần hai sẽ mất phần lớn các mã của bạn. Cuối cùng, một phần ba là trên đường 58, nơi chúng tôi đóng file. Ở đây chúng ta gọi fclose và vượt qua nó con trỏ tập tin ban đầu của chúng tôi. Trong dòng tiếp theo, chúng tôi trở về số không, báo hiệu sự kết thúc của chương trình của chúng tôi. Và, có, một phần ba là đơn giản như vậy. Hãy di chuyển để đọc từ các tập tin. Trở lại trong thư mục của chúng tôi, chúng tôi có một tập tin gọi printer.c. Hãy để chạy nó với các tập tin chúng ta vừa tạo - doc.txt. Chương trình này, như tên cho thấy, chỉ đơn giản là sẽ in ra nội dung của tập tin được truyền cho nó. Và chúng tôi đã có nó. Các dòng mã, chúng tôi đã nhập trước đó và lưu trong doc.txt. Hi. Tên tôi là Jason. Nếu chúng ta đi sâu vào printer.c, chúng ta thấy rằng rất nhiều của mã này trông tương tự như những gì chúng tôi vừa đi qua trong typewriter.c. Thực tế dòng 22, chúng tôi đã mở các tập tin, và dòng 39, nơi chúng tôi đóng tập tin, cả hai đều gần giống như typewriter.c, tiết kiệm cho lập luận fopen thứ hai. Thời gian này chúng tôi đang đọc từ một tập tin, vì vậy chúng tôi đã chọn r thay vì của w. Như vậy, chúng ta hãy tập trung vào phần thứ hai của quá trình này. Trong dòng 35, là điều kiện thứ hai trong vòng 4 của chúng tôi, chúng tôi thực hiện cuộc gọi fgets chức năng đồng hành với fputs từ trước. Lần này, chúng tôi có ba đối số. Đầu tiên là con trỏ đến các mảng của các ký tự chuỗi sẽ được lưu trữ. Thứ hai là số ký tự tối đa để được đọc. Và thứ ba là con trỏ đến các tập tin mà chúng ta đang làm việc. Bạn sẽ nhận thấy rằng cho vòng lặp kết thúc khi fgets trả về null. Có hai lý do rằng điều này có thể xảy ra. Đầu tiên, một lỗi có thể đã xảy ra. Thứ hai, và nhiều khả năng, sự kết thúc của tập tin đã đạt được và ký tự không được đọc. Trong trường hợp bạn đang tự hỏi, hai chức năng tồn tại cho phép chúng tôi để lý do là nguyên nhân gây ra cho con trỏ null cụ thể. Và, không có gì đáng ngạc nhiên, kể từ khi họ có để làm với làm việc với các tập tin, cả hai chức năng ferror và bắt đầu chức năng feof với chữ f. Cuối cùng, trước khi chúng tôi kết luận, một lưu ý nhanh chóng về sự kết thúc của chức năng tập tin, trong đó, như vừa đề cập, được viết như feof. Thường thì bạn sẽ tìm thấy chính mình bằng cách sử dụng thời gian và cho các vòng để dần dần đọc theo cách của bạn thông qua các file. Vì vậy, bạn sẽ cần một cách để kết thúc những vòng sau khi bạn đến cuối của những tập tin này. Gọi feof trên con trỏ tập tin của bạn và kiểm tra để xem nếu nó là sự thật sẽ làm điều đó. Do đó, một vòng lặp trong khi với điều kiện (feof (fp)) có vẻ như một giải pháp hoàn toàn thích hợp. Tuy nhiên, nói rằng chúng tôi có một dòng còn lại trong tập tin văn bản của chúng tôi. Chúng tôi sẽ nhập vào vòng lặp trong khi của chúng tôi và tất cả mọi thứ sẽ làm việc theo kế hoạch. Vòng tiếp theo thông qua, chương trình của chúng tôi sẽ kiểm tra xem nếu feof fp là đúng, nhưng - và đây là điểm rất quan trọng để hiểu ở đây - nó sẽ không là sự thật chỉ được nêu ra. Đó là bởi vì mục đích của feof không phải là để kiểm tra nếu cuộc gọi bên cạnh một chức năng đọc sẽ được tung ra cuối của tập tin, mà là để kiểm tra hay không cuối của tập tin đã đạt được. Trong trường hợp của ví dụ này, đọc dòng cuối cùng của tập tin của chúng tôi đi hoàn toàn trơn tru, nhưng chương trình không biết rằng chúng tôi đã đạt kết thúc của tập tin của chúng tôi. Nó không phải cho đến khi nó làm một đọc thêm mà nó đếm cuối của tập tin. Như vậy, một điều kiện chính xác sẽ được như sau: fgets và ba đối số - đầu ra, kích thước của đầu ra, và fp - và tất cả các điều đó không bằng giá trị null. Đây là cách tiếp cận chúng tôi đã printer.c, và trong trường hợp này, sau khi thoát khỏi vòng lặp, bạn có thể gọi feof hoặc ferror để thông báo cho người sử dụng như các lý do cụ thể để thoát khỏi vòng lặp này. Viết và đọc từ một tập tin, tại cơ bản nhất của nó, a 3-một phần quá trình đơn giản. Đầu tiên, chúng ta mở tập tin. Thứ hai, chúng tôi đặt một số điều vào tập tin của chúng tôi hoặc mất một số thứ ra khỏi nó. Thứ ba, chúng tôi đóng tập tin. Các bộ phận đầu tiên và cuối cùng là dễ dàng. Phần giữa là nơi mà các công cụ phức tạp nằm. Và mặc dù bên dưới mui xe chúng tôi luôn phải đối đầu với một chuỗi dài các số không và những người thân, nó sẽ giúp khi mã hóa để thêm một lớp trừu tượng biến chuỗi thành một cái gì đó rất giống với những gì chúng tôi đang sử dụng để nhìn thấy. Ví dụ, nếu chúng ta đang làm việc với một tập tin bitmap 24-bit, chúng tôi có khả năng sẽ được đọc hoặc viết ba byte tại một thời điểm. Trong trường hợp đó, nó sẽ làm cho tinh thần để xác định và thích hợp tên một cấu trúc là 3 byte lớn. Mặc dù làm việc với các tập tin có thể có vẻ phức tạp, sử dụng chúng cho phép chúng ta làm một cái gì đó thật sự đáng chú ý. Chúng ta có thể thay đổi trạng thái của thế giới bên ngoài chương trình của chúng tôi, chúng ta có thể tạo ra một cái gì đó sống vượt ra ngoài cuộc sống của chương trình của chúng tôi, hoặc chúng ta thậm chí có thể thay đổi một cái gì đó đã được tạo ra trước khi chương trình của chúng tôi bắt đầu chạy. Tương tác với các tập tin là một phần thực sự mạnh mẽ của chương trình trong C. và tôi vui mừng để xem những gì bạn đang đi để tạo ra với nó trong mã đến. Tên tôi là Jason Hirschhorn. Đây là CS50. [CS50.TV] [Cười] Okay. Một lần quay. Ở đây chúng tôi đi. Khi chúng ta nghĩ về một tập tin - >> Oh, chờ đợi. Xin lôi. [Cười] Okay. Hey there. Khi chúng ta nghĩ về một tập tin - Khi bạn nghĩ của một tập tin - Được rồi. Cho tôi biết khi bạn đã sẵn sàng. Oh, tuyệt vời. Mặc dù đọc từ một Teleprompter có vẻ như không có. Xấu của tôi.