2008-11-14 27 views
8

Giả sử bạn có hai tệp lớn (vài GB) mà bạn muốn nối với nhau, nhưng bạn có rất ít không gian đĩa dự phòng (giả sử một vài trăm MB). Tức là, với file1file2, bạn muốn kết thúc bằng một tệp duy nhất là kết quả của việc ghép nối file1file2 cùng nhau byte-cho-byte và xóa các tệp gốc.Làm thế nào bạn có thể nối hai tệp lớn với rất ít không gian đĩa trống?

Bạn không thể làm rõ ràng cat file2 >> file1; rm file2, vì ở giữa hai thao tác, bạn sẽ hết dung lượng đĩa.

Các giải pháp trên mọi nền tảng có công cụ miễn phí hoặc không miễn phí đều được chào đón; đây là một vấn đề giả định tôi nghĩ trong khi tôi đang tải xuống một Linux ISO ngày khác, và việc tải xuống bị gián đoạn một phần do một trục trặc không dây.

+1

Tôi thực sự khuyên bạn nên kiểm tra chữ ký tệp sau khi hoàn thành. Điều này sẽ giúp bạn tiết kiệm rất nhiều rắc rối sau này nếu một trong các bộ phận bị hỏng. –

Trả lời

8

Tôi nghĩ khó khăn là xác định cách không gian có thể được phục hồi từ các tệp gốc.

Tôi nghĩ rằng những điều sau đây có thể làm việc:

  1. Cấp phát một tập tin thưa thớt của kích thước kết hợp.
  2. Sao chép 100Mb từ cuối tệp thứ hai vào cuối tệp mới.
  3. Cắt ngắn 100Mb vào cuối tệp thứ hai
  4. Vòng 2 & 3 cho đến khi bạn hoàn tất tệp thứ hai (Với 2. sửa đổi đúng vị trí trong tệp đích).
  5. Làm 2 4 nhưng với tệp thứ nhất.

Tất cả điều này phụ thuộc vào hỗ trợ tệp thưa thớt và không gian giải phóng cắt tệp ngay lập tức.

Nếu bạn thực sự muốn thực hiện điều này thì bạn nên điều tra lệnh dd. mà có thể làm các bước sao chép

người trong câu trả lời khác đã đưa ra một giải pháp gọn gàng mà không yêu cầu tập tin thưa thớt, nhưng không sao chép file2 hai lần:

  1. Sao chép 100Mb khối từ ngày kết thúc tập tin từ 2 đến mới tệp 3, kết thúc theo thứ tự ngược lại. Cắt bớt tập tin 2 khi bạn đi.
  2. Sao chép 100Mb khối từ phần cuối của tệp 3 vào tệp 1, kết thúc với các khối theo thứ tự ban đầu của chúng, ở cuối tệp 1. Cắt bớt tệp 3 khi bạn đi.
+0

Ông có thể sử dụng dd cho việc này. –

+0

Vâng tôi đã nghĩ đến dd, nhưng điều này có vẻ giống như một cuộc thảo luận lý thuyết. –

4

Với những ràng buộc đó, tôi hy vọng bạn sẽ cần phải giả mạo hệ thống tệp; chỉnh sửa trực tiếp kích thước tệp và khối phân bổ.

Nói cách khác, hãy quên xáo trộn bất kỳ khối nội dung tệp nào xung quanh, chỉ cần chỉnh sửa thông tin về các tệp đó.

1

Rủi ro về âm thanh flippant, bạn có cân nhắc tùy chọn chỉ nhận được đĩa lớn hơn không? Nó có lẽ sẽ nhanh hơn ...

+0

Đó là một câu hỏi giả định - trong trường hợp của tôi, tôi (hầu như) có đủ không gian đĩa trống để làm con mèo. Người ta cũng có thể dễ dàng sử dụng các phương tiện bên ngoài như một khóa USB. –

+0

Vâng, tôi đánh giá cao đó là một câu hỏi giả định. Chỉ muốn chắc chắn rằng giải pháp thực tế nhàm chán đã được đại diện, cùng với những cái xáo trộn byte thông minh;) –

+0

Tôi thấy suy nghĩ rằng luôn luôn có một số cách để có thêm không gian gây phiền nhiễu. Sau khi tất cả, đó cũng luôn luôn là một số cách để có được các tập tin lớn hơn. – Svante

0

Hai suy nghĩ:

Nếu bạn có đủ RAM vật lý, bạn thực sự có thể đọc các tập tin thứ hai hoàn toàn vào bộ nhớ, xóa nó, sau đó viết nó trong chế độ append vào file đầu tiên. Tất nhiên nếu bạn mất quyền lực sau khi xóa nhưng trước khi hoàn thành việc viết, bạn đã mất một phần của tập tin thứ hai cho tốt.

Tạm thời giảm dung lượng đĩa được sử dụng bởi chức năng OS (ví dụ: bộ nhớ ảo, "thùng rác" hoặc tương tự). Có lẽ chỉ sử dụng trên Windows.

0

Tôi nghi ngờ đây là câu trả lời trực tiếp cho câu hỏi. Bạn có thể xem đây là một cách khác để giải quyết vấn đề.

Tôi nghĩ rằng có thể xem xét tệp thứ 2 là phần 2 của tệp đầu tiên. Thông thường trong ứng dụng zip, chúng ta sẽ thấy một tệp lớn được chia thành nhiều phần. Nếu bạn mở phần đầu tiên, ứng dụng sẽ tự động xem xét các phần khác trong quá trình xử lý tiếp theo.

Chúng tôi có thể mô phỏng điều tương tự ở đây. Như @edg đã chỉ ra, hệ thống tệp tinkering sẽ là một cách.

15

thời gian dành cho việc tìm ra giải pháp thông minh liên quan đến đĩa ngành xáo trộn và thao tác tập tin chuỗi: 2-4 giờ

thời gian dành cho việc mua/viết phần mềm để làm bản sao tại chỗ và cắt ngắn: 2-20 giờ

lần trung bình tỷ lệ lập trình viên $ 50/hr: $ 400- $ 1200

chi phí của ổ đĩa USB 1TB: $ 100- $ 200

khả năng hiểu cụm từ "chi phí cơ hội": vô

+8

kiến ​​thức thu được từ bài tập lý thuyết: vô giá –

+0

@edg: hoặc vô giá trị trừ khi bạn có thể áp dụng nó để kiếm tiền sau ;-) –

+0

Có tiếng cười của tôi! Trong khi tôi đồng ý với điểm này, tôi sẽ thêm rằng cuối cùng cùng một vấn đề lặp lại chính nó. – Josh

1

Không phải là rất hiệu quả, nhưng tôi nghĩ rằng nó có thể được thực hiện.

Mở tệp đầu tiên ở chế độ chắp thêm và sao chép các khối từ tệp thứ hai vào tệp cho đến khi đĩa gần đầy. Đối với phần còn lại của tệp thứ hai, hãy sao chép các khối từ điểm mà bạn đã dừng lại ở đầu tệp thông qua truy cập ngẫu nhiên I/O. Cắt bớt tệp sau khi bạn đã sao chép khối cuối cùng. Lặp lại cho đến khi kết thúc.

1

ok, để giải trí lý thuyết, và chỉ khi bạn hứa sẽ không để lãng phí thời gian của bạn thực sự làm việc đó:

  • tập tin được lưu trữ trên đĩa trong mảnh
  • các mảnh được liên kết trong một chuỗi

Vì vậy, bạn có thể nối các file bằng cách:

  • nối những mảnh cuối cùng của tập tin đầu tiên để phần đầu tiên của tập tin cuối cùng
  • thay đổi mục nhập thư mục cho các tập tin đầu tiên để thay đổi những mảnh cuối cùng và kích thước tập tin
  • loại bỏ các mục nhập thư mục cho các tập tin cuối cùng
  • dọn dẹp các tập tin đầu tiên của end-of- đánh dấu tập tin, nếu có
  • lưu ý rằng nếu phân đoạn cuối cùng của tệp đầu tiên chỉ được điền một phần, bạn sẽ phải sao chép dữ liệu "lên" các phân đoạn của tệp cuối cùng để tránh có rác ở giữa tệp [cảm ơn @Wedge!]

Điều này sẽ có hiệu quả tối ưu: thay đổi tối thiểu, sao chép tối thiểu, không cần dung lượng đĩa trống.

bây giờ đi mua một ổ usb ;-)

+0

Trừ khi kích thước của tệp thứ nhất là bội số nguyên của cụm sao cụm cuối cùng sẽ trống một phần, vì vậy tệp được liên kết sẽ có rác ở giữa . Tôi không thể nhìn thấy bất kỳ cách nào để làm điều này trong trường hợp chung mà tránh phải chuyển dữ liệu trong tập tin thứ 2. – Wedge

+0

@ [Wedge]: tốt điểm, chỉnh sửa để phản ánh –

1

Rõ ràng, câu trả lời là kinh tế mua thêm lưu trữ giả định rằng một câu trả lời có thể. Nó có thể không được, mặc dù - hệ thống nhúng không có cách nào để đính kèm thêm lưu trữ, hoặc thậm chí không có quyền truy cập vào các thiết bị chính nó - nói, thăm dò không gian trong chuyến bay.

Câu trả lời được trình bày trước đây dựa trên hệ thống tệp thưa thớt là tốt (trừ bản chất phá hoại của nó nếu có sự cố!) Nếu bạn có hệ thống tệp thưa thớt. Điều gì sẽ xảy ra nếu bạn không làm vậy?

Bắt đầu từ cuối tệp 2 khối bản sao để bắt đầu tệp mục tiêu đảo ngược chúng khi bạn thực hiện. Sau mỗi khối bạn cắt ngắn tệp nguồn thành độ dài chưa được kiểm tra. Lặp lại cho tập tin # 1.

Tại thời điểm này, tệp đích chứa tất cả dữ liệu ngược, các tệp nguồn đã biến mất.

Đọc một khối từ tart và từ cuối tệp đích, đảo ngược và ghi chúng vào vị trí của thẻ còn lại. Làm việc theo cách của bạn flipping khối.

Khi bạn hoàn thành, tệp đích là kết nối của các tệp nguồn. Không cần hệ thống tệp thưa thớt, không gây rối với hệ thống tệp cần thiết. Điều này có thể được thực hiện ở mức không byte miễn phí vì dữ liệu có thể được giữ trong bộ nhớ.

6

Đây là cải thiện nhỏ so với first answer của tôi.

Nếu bạn có 100MB miễn phí, hãy sao chép 100MB cuối cùng từ tệp thứ hai và tạo tệp thứ ba. Cắt bớt tệp thứ hai để nó nhỏ hơn 100MB. Lặp lại quá trình này cho đến khi tệp thứ hai đã được phân tách hoàn toàn thành các khối 100MB riêng lẻ.

Bây giờ, mỗi tệp 100MB đó có thể được nối vào tệp đầu tiên, mỗi lần một tệp.

0

bạn có thể làm điều này:

head file2 --bytes=1024 >> file1 && tail --bytes=+1024 file2 >file2 

bạn có thể tăng 1024 theo thêm bao nhiêu không gian đĩa mà bạn có, sau đó chỉ cần lặp lại này cho đến khi tất cả các byte đã được di chuyển.

Đây có lẽ là cách nhanh nhất để làm điều đó (về thời gian phát triển)

+0

Điều này về bản chất giống như giải pháp của Dave Costa - lệnh đuôi sẽ tải tất cả trừ 1024 byte đầu tiên của tệp2 vào bộ nhớ và sau đó là tệp 2. Nếu có sự cố mất điện, bạn có nguy cơ mất một lượng lớn dữ liệu vĩnh viễn. –

+0

Tôi nghĩ rằng điều này bị hỏng như được viết. Shell sẽ thực hiện chuyển hướng trước khi 'file2' được đọc bởi' tail', nuking nó. – msandiford

0

Bạn có thể để đạt được không gian bằng cách nén toàn bộ hệ thống tập tin. Tôi tin rằng NTFS hỗ trợ điều này, và tôi chắc chắn có những hương vị của hệ thống tập tin * nix có thể hỗ trợ nó. Nó cũng sẽ có lợi ích sau khi sao chép các tập tin bạn sẽ vẫn còn nhiều không gian đĩa còn lại hơn khi bạn bắt đầu.

0

OK, thay đổi vấn đề một chút. Rất có thể là có những thứ khác trên đĩa mà bạn không cần, nhưng bạn không biết nó là gì hoặc nó ở đâu. Nếu bạn có thể tìm thấy nó, bạn có thể xóa nó, và sau đó có thể bạn sẽ có đủ không gian.

Để tìm những "khối u" này, dù một vài khối u lớn, hay một vài khối nhỏ, tôi sử dụng một chương trình lấy mẫu nhỏ. Bắt đầu từ phía trên cùng của một thư mục (hoặc thư mục gốc) nó tạo ra hai đường chuyền. Trong đèo 1, nó đi vào cây thư mục, thêm kích thước của tất cả các tệp để có tổng số N byte. Trong pass 2, nó lại đi trên cây thư mục, giả vờ nó đang đọc từng file.Mỗi lần nó vượt qua N/20 byte, nó in ra đường dẫn thư mục và tên của tập tin đó là "đọc". Vì vậy, kết quả cuối cùng là 20 mẫu sâu của tên đường dẫn thống nhất trải rộng trên tất cả các byte trong thư mục.

Sau đó, chỉ cần nhìn vào danh sách đó cho những thứ hiển thị rất nhiều mà bạn không cần, và thổi nó đi.

(. Đó là không gian tương đương của phương pháp lấy mẫu tôi sử dụng để tối ưu hóa hiệu suất)

2

nếu các tập tin là rất nén (. Tức là các bản ghi):

gzip file1 

gzip file2 

zcat file1 file2 | gzip > file3 

rm file1 

rm file2 

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