2009-04-01 38 views
14

Một vấn đề mà tôi đang làm gần đây khiến tôi ước rằng mình có thể lop ra phía trước tập tin. Giống như một "truncate ở phía trước," nếu bạn muốn. Cắt bớt một tập tin ở phía sau là một hoạt động phổ biến - một cái gì đó chúng ta làm mà không cần suy nghĩ nhiều về nó. Nhưng lopping ra phía trước của một tập tin? Nghe có vẻ vô lý lúc đầu, nhưng chỉ vì chúng tôi đã được đào tạo để nghĩ rằng điều đó là không thể. Nhưng một hoạt động lop có thể hữu ích trong một số trường hợp.Cắt ngắn tập tin ở mặt trước

Một ví dụ đơn giản (chắc chắn không phải là ví dụ duy nhất hoặc nhất thiết là ví dụ tốt nhất) là hàng đợi FIFO. Bạn đang thêm các mục mới vào cuối tệp và kéo các mục ra khỏi tệp từ phía trước. Tệp phát triển theo thời gian và có một không gian trống lớn ở phía trước. Với hệ thống tập tin hiện nay, có một số cách giải quyết vấn đề này:

  • Như từng hạng mục được lấy ra, sao chép mục còn lại lên để thay thế nó, và cắt file. Mặc dù nó hoạt động, giải pháp này rất tốn kém theo thời gian.
  • Theo dõi kích thước của không gian trống tại mặt trước và khi đạt đến kích thước hoặc tỷ lệ riêng của toàn bộ kích thước tệp, di chuyển mọi thứ lên và cắt bớt tệp. Điều này là nhiều hiệu quả hơn so với giải pháp trước đó, nhưng vẫn còn chi phí thời gian khi mục được di chuyển trong tệp.
  • Thực hiện hàng đợi hình tròn trong tệp , thêm các mục mới vào lỗ ở mặt trước của tệp là các mục được loại bỏ. Điều này có thể khá hiệu quả, đặc biệt là nếu bạn không quan tâm đến việc khả năng xảy ra sự cố khi thoát khỏi số trong hàng đợi. Nếu bạn quan tâm về đơn đặt hàng, có khả năng phải di chuyển các mục xung quanh. Nhưng trong chung, hàng đợi hình tròn là khá dễ thực hiện và quản lý không gian đĩa tốt.

Nhưng nếu có thao tác lop, việc xóa một mục khỏi hàng đợi sẽ dễ dàng như việc cập nhật điểm đánh dấu đầu tệp. Thật dễ dàng, trên thực tế, như cắt ngắn một tập tin. Tại sao, sau đó, không có hoạt động như vậy?

Tôi hiểu một chút về việc triển khai hệ thống tệp và không thấy bất kỳ lý do cụ thể nào điều này sẽ khó. Dường như với tôi như tất cả nó sẽ yêu cầu là một từ (dword, có lẽ?) Cho mỗi mục phân bổ để nói nơi tập tin bắt đầu trong khối. Với 1 terabyte ổ đĩa dưới $ 100 Mỹ, nó có vẻ như một mức giá khá nhỏ để trả tiền cho các chức năng như vậy.

Nhiệm vụ nào khác sẽ được thực hiện dễ dàng hơn nếu bạn có thể lop ra khỏi mặt trước của một tệp hiệu quả như bạn có thể cắt ngắn ở cuối?

Bạn có thể nghĩ ra bất kỳ lý do kỹ thuật nào mà chức năng này không thể được thêm vào hệ thống tệp hiện đại không? Các lý do khác, phi kỹ thuật?

+2

Một lợi thế lớn của một hoạt động như vậy là nó sẽ tránh chu kỳ xóa trên phương tiện truyền thông flash. – Michael

+0

Trong thời gian chờ đợi, chủ đề này đã là một lỗi trong trang "man truncate". Tôi chắc chắn một ngày nào đó nó sẽ được thực hiện, 20 năm sau khi tôi lần đầu tiên yêu cầu nó – Lothar

+0

cùng một vấn đề như: http://stackoverflow.com/questions/339483/how-can-i-remove-the-first-line- of-a-text-file-using-bash-sed-script mặc dù rõ ràng hơn ở đây –

Trả lời

5

Các tệp cắt ngắn ở phía trước dường như không khó thực hiện ở cấp hệ thống.

Nhưng có vấn đề.

  • Thứ nhất ở cấp độ lập trình. Khi mở tệp truy cập ngẫu nhiên, mô hình hiện tại là sử dụng bù đắp từ đầu tệp để chỉ ra các vị trí khác nhau trong tệp. Nếu chúng ta cắt bớt ở đầu tập tin (hoặc thực hiện chèn hoặc loại bỏ từ giữa tập tin) mà không phải là bất kỳ tài sản ổn định hơn. (Trong khi appendind hoặc cắt xén từ cuối không phải là một vấn đề).

Nói cách khác cắt ngắn phần đầu sẽ thay đổi điểm tham chiếu duy nhất và điều đó là xấu.

  • Ở mức sử dụng hệ thống tồn tại như bạn đã chỉ ra, nhưng khá hiếm. Tôi tin rằng hầu hết việc sử dụng các tập tin là viết một lần đọc nhiều loại, do đó, ngay cả cắt ngắn không phải là một tính năng quan trọng và chúng tôi có thể làm mà không có nó (một số điều sẽ trở nên khó khăn hơn, nhưng không có gì sẽ trở thành không thể).

Chúng tôi muốn truy cập phức tạp hơn (và thực sự cần) chúng tôi mở tệp ở chế độ ngẫu nhiên và thêm một số thông tin cấu trúc bên trong. Thông tin này cũng có thể được chia sẻ giữa nhiều tệp. Điều này dẫn chúng ta đến vấn đề cuối cùng tôi thấy, có lẽ là quan trọng nhất.

  • Trong ý nghĩa khi chúng tôi sử dụng tệp truy cập ngẫu nhiên với cấu trúc bên trong ... chúng tôi vẫn sử dụng tệp nhưng chúng tôi không còn sử dụng mô hình tệp nữa. Trường hợp điển hình như vậy là cơ sở dữ liệu mà chúng tôi muốn thực hiện chèn hoặc xóa hồ sơ mà không cần quan tâm gì về địa điểm thực của chúng. Cơ sở dữ liệu có thể sử dụng các tệp dưới dạng triển khai ở mức độ thấp nhưng vì mục đích tối ưu hóa, một số trình chỉnh sửa cơ sở dữ liệu chọn hoàn toàn bỏ qua hệ thống tệp (suy nghĩ về các phân vùng Oracle).

Tôi không thấy lý do kỹ thuật tại sao chúng tôi không thể làm mọi thứ hiện được thực hiện trong hệ điều hành với tệp bằng cơ sở dữ liệu làm lớp lưu trữ dữ liệu. Tôi thậm chí còn nghe nói rằng NTFS có nhiều điểm chung với cơ sở dữ liệu trong nội bộ của nó. Một hệ điều hành có thể (và có lẽ sẽ ở một số tính năng không xa) sử dụng một mô hình khác so với tệp một. Nói chung tôi tin rằng không có vấn đề gì về kỹ thuật, chỉ cần thay đổi mô hình và loại bỏ sự khởi đầu chắc chắn không có trong mô hình tập tin hiện tại, nhưng không phải là một thay đổi lớn và hữu ích để bắt buộc thay đổi bất cứ thứ gì.

0

Tôi nghĩ rằng có một chút vấn đề về trứng và gà trong đó: vì hệ thống tệp không hỗ trợ loại hành vi này hiệu quả, mọi người chưa viết chương trình để sử dụng và vì mọi người chưa viết chương trình sử dụng nó, có rất ít động lực cho các hệ thống tập tin để hỗ trợ nó.

Bạn luôn có thể viết hệ thống tệp riêng của mình để thực hiện việc này hoặc có thể sửa đổi hệ thống tệp hiện có (mặc dù hệ thống tệp được sử dụng "trong tự nhiên" có thể khá phức tạp, bạn có thể dễ dàng bắt đầu từ đầu).Nếu mọi người thấy nó đủ hữu ích, nó có thể bắt đầu ;-)

0

Thực ra có các hệ thống tệp cơ sở bản ghi - IBM có một và tôi tin rằng DEC VMS cũng có cơ sở này. Tôi dường như nhớ cả hai cho phép (cho phép? Tôi đoán họ vẫn còn xung quanh) xóa và chèn vào vị trí ngẫu nhiên trong một tập tin.

1

NTFS có thể làm điều gì đó như thế này với sự hỗ trợ tệp thưa thớt nhưng nó thường không hữu ích.

12

Trên các hệ thống tệp hỗ trợ tệp thưa thớt "đục lỗ" một lỗ và xóa dữ liệu ở vị trí tệp tùy ý rất dễ dàng. Hệ điều hành chỉ cần đánh dấu các khối tương ứng là "không được cấp phát". Việc xóa dữ liệu từ đầu tệp chỉ là trường hợp đặc biệt của thao tác này. Điều chính được yêu cầu là một cuộc gọi hệ thống sẽ thực hiện một thao tác như vậy: ftruncate2 (int fd, offset off_t, size_t count).

Trên hệ thống Linux, hệ thống này thực sự được thực hiện với cuộc gọi hệ thống fallocate bằng cách chỉ định cờ FALLOC_FL_PUNCH_HOLE cho không có dải ô và cờ FALLOC_FL_COLLAPSE_RANGE để xóa hoàn toàn dữ liệu trong phạm vi đó. Lưu ý rằng có những hạn chế về phạm vi nào có thể được chỉ định và không phải tất cả các hệ thống tệp đều hỗ trợ các hoạt động này.

+0

Ngoài ra, cờ liên quan thú vị 'FALLOC_FL_COLLAPSE_RANGE'. – catpnosis

+0

Cảm ơn, tôi đã thêm điều đó. –

0

Ngoài ra còn có một lệnh unix gọi head - vì vậy bạn có thể làm điều này qua:

head -n1000 file > file_truncated 
+0

câu trả lời trùng lặp, giống như 'tail +1000> file_truncated' – user3338098

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