2011-12-09 42 views
6

Có nhiều câu hỏi tương tự, nhưng không có câu trả lời cụ thể sau khi googling xung quanh khá một chút. Ở đây đi:Cách tốt nhất để cắt bớt phần đầu của một tập tin trong C là gì?

Giả sử chúng ta có một tập tin (có thể là nhị phân, và lớn hơn nhiều quá):

abcdefghijklmnopqrztuvwxyz

gì là cách tốt nhất trong C để "di chuyển" quyền nhất phần của tập tin này sang bên trái, cắt bỏ phần đầu của tập tin .. như vậy, ví dụ, "phía trước cắt xén" 7 byte sẽ thay đổi các tập tin trên đĩa là:

hijklmnopqrztuvwxyz

Tôi phải tránh các tệp tạm thời và không muốn sử dụng bộ đệm lớn để đọc toàn bộ tệp vào bộ nhớ. Một phương pháp có thể tôi nghĩ là sử dụng fopen với cờ "rb +", và liên tục fseek qua lại đọc và ghi để sao chép byte bắt đầu từ offset đến đầu, sau đó setEndOfFile để cắt ngắn ở cuối. Điều đó có vẻ là rất nhiều tìm kiếm (có thể không hiệu quả).

Một cách khác là để fopen cùng một tệp hai lần, và sử dụng fgetc và fputc với các con trỏ tệp tương ứng. Điều này thậm chí có thể?

Nếu có nhiều cách khác, tôi muốn đọc tất cả chúng.

+0

Tôi đã mở tệp hai lần (với hai con trỏ FILE). Điều này rất nhanh (~ 2mb trong nháy mắt, không chuẩn). Tôi đã sử dụng ftruncate() với fileno() và ftell(). – snapfractalpop

Trả lời

3

Bạn không cần phải sử dụng kích thước bộ đệm khổng lồ và hạt nhân sẽ thực hiện công việc khó khăn cho bạn, nhưng có, đọc bộ đệm đầy đủ từ tệp và viết gần đầu là cách làm điều đó nếu bạn không thể đủ khả năng để làm công việc đơn giản hơn để tạo một tệp mới, sao chép những gì bạn muốn vào tệp đó và sau đó sao chép tệp (tạm thời) mới trên tệp cũ. Tôi sẽ không loại trừ khả năng rằng cách tiếp cận sao chép những gì bạn muốn vào một tập tin mới và sau đó di chuyển tập tin mới thay cho cũ hoặc sao chép mới hơn cũ sẽ nhanh hơn quá trình xáo trộn bạn mô tả. Nếu số lượng byte được loại bỏ là kích thước khối đĩa, thay vì 7 byte, tình hình có thể khác, nhưng có thể không. Nhược điểm duy nhất là phương pháp sao chép đòi hỏi không gian đĩa trung gian hơn.

Phương pháp tiếp cận phác thảo của bạn sẽ yêu cầu sử dụng truncate() hoặc ftruncate() để rút ngắn tệp xuống đúng độ dài, giả sử bạn đang sử dụng hệ thống POSIX. Nếu bạn không có truncate(), thì bạn sẽ cần thực hiện sao chép.

Lưu ý rằng việc mở các tập tin hai lần sẽ làm việc OK nếu bạn cẩn thận không để clobber tập tin khi mở để viết - sử dụng "r+b" chế độ với fopen(), hoặc tránh O_TRUNC với open().

+0

cảm ơn bạn đã phản hồi rất tốt! kích thước của các khối để di chuyển có thể đáng kể (theo thứ tự megabyte). Mối quan ngại của tôi về việc tránh các tệp tạm thời không phải là không gian, mà là sự kiên trì của dữ liệu nhạy cảm. Tôi muốn giới hạn lưu trữ vật lý của byte đến một nơi trên đĩa (mặc dù bản sao bị xóa, các byte vẫn có thể có mặt). BTW, tôi đang sử dụng Linux.Hạt nhân sẽ làm công việc khó khăn nếu tôi đang tìm kiếm qua lại từng byte, hoặc bộ đệm tối ưu sẽ là gì nếu không? Tôi tự hỏi nếu tùy chọn cuối cùng sẽ dẫn đến cùng một điều thể chất xảy ra. – snapfractalpop

+0

Nếu bạn thực hiện thao tác đọc và ghi byte đơn, bạn sẽ làm một cái gì đó (tiêu chuẩn I/O hoặc hạt nhân - hoặc có lẽ cả hai) thực hiện rất nhiều công việc. Làm việc trong các khối có kích thước kilobyte (nói 1, 2, 4, 8, 16, 32 khối KiB) sẽ hiệu quả hơn, mà không nhấn mạnh tất cả trừ những môi trường nghèo nàn nhất. Hạt nhân sẽ đối phó với sự sắp xếp vv cho bạn - may mắn thay. –

+0

ok. cảm ơn một lần nữa! – snapfractalpop

4

Bạn có thể mmap tệp vào bộ nhớ và sau đó ghi nhớ nội dung. Bạn sẽ phải cắt bớt tệp một cách riêng biệt.

+0

Vì vậy, các bước sẽ là: 1) mmap 2) memmove 3) un-mmap (điều này tồn tại?) 4) cắt ngắn ? – snapfractalpop

+1

@snapfractalpop [ví dụ liên quan tại đây] (http://pastebin.com/s1vSCvxA). Giải pháp này có tiềm năng thực sự nhanh, nhưng kích thước tệp bị giới hạn bởi kích thước vùng địa chỉ. Bạn sẽ không thể cắt bớt các tệp lớn (> 4GB) trên các hệ thống 32 bit. –

+2

@Banthar: nó tồi tệ hơn thế: bạn cần một phần tiếp giáp trong không gian địa chỉ của quá trình đủ lớn. Điều đó có thể ít hơn 4GB, tùy thuộc vào phân mảnh và phân bổ bộ nhớ khác. – Joe

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