2008-11-14 72 views
8

假設您有兩個想要並置在一起的大文件(幾GB),但您的備用磁盤空間非常少(比如說幾百MB)。也就是說,如果給出file1file2,您希望最終得到一個文件,這個文件是將file1file2連接在一起逐個字節的結果,並刪除原始文件。如何連接兩個大容量文件,而且磁盤空間非常小?

你不能做明顯的cat file2 >> file1; rm file2,因爲在這兩個操作之間,你會用完磁盤空間。

歡迎任何和所有平臺上的免費或非免費工具解決方案;這是我前些日子在下載Linux ISO時想到的一個假想問題,由於無線打嗝,下載在中途被中斷。

+1

我強烈建議您在完成後檢查文件簽名。如果任一部件損壞,這將爲您節省很多麻煩。 – 2008-11-14 17:25:41

回答

8

我認爲困難在於如何從原始文件恢復空間。

我認爲有以下可能的工作:

  1. 分配 組合大小的稀疏文件。
  2. 從第二個文件的末尾複製100Mb到新文件的末尾。
  3. 截斷第二個文件末尾的100Mb
  4. 迴路2 & 3直到您完成第二個文件(將2.修改爲目標文件中的正確位置)。
  5. 做2 2 4但與第一個文件。

這一切都依賴於稀疏文件支持,並立即釋放文件空間。

如果你真的想這樣做,那麼你應該調查dd命令。它可以做拷貝步驟

有人在另一個答案給了一個整潔的解決方案,不需要稀疏文件,但並複製文件2兩次:

    從文件2月底
  1. 複製100Mb的數據塊到一個新的文件3,以相反的順序結束。截斷文件2。
  2. 將文件3末尾的100Mb塊從文件1複製到文件1中,最後以文件1的結尾按原始順序結束。截斷文件3。
+0

他可以爲此使用dd。 – 2008-11-14 17:09:11

+0

是的,我在想dd,但這似乎是一個理論上的討論。 – 2008-11-17 22:14:43

4

有了這些限制,我希望你需要篡改文件系統;直接編輯文件大小和分配塊。

換句話說,忘記隨便翻動任何文件內容塊,只需編輯有關這些文件的信息即可。

1

在冒着風吹草動的風險,你有沒有考慮過選擇一個更大的磁盤?它可能會更快......

+0

這是一個假想的問題 - 就我而言,我(幾乎沒有)有足夠的磁盤空間來做貓。人們也可以很容易地利用外部媒體,如USB鑰匙。 – 2008-11-14 17:03:04

+0

是的,我很感激這是一個假設的問題。只是想確保無聊的實際解決方案,以及聰明的字節洗牌; – 2008-11-14 17:18:50

+0

我覺得總是有一些方法來獲得更多的空間煩人的想法。畢竟,總有一些方法可以獲得更大的文件。 – Svante 2008-11-14 18:26:47

0

兩個想法:

如果你有足夠的物理內存,你可以真正閱讀的第二個文件全部裝入內存,刪除它,然後將它追加模式寫入第一個文件。當然,如果您在刪除之後但在完成寫入之前斷電,您已經失去了部分第二個文件。

暫時減少操作系統功能使用的磁盤空間(例如虛擬內存,「回收站」或類似的東西)。可能只在Windows上使用。

0

我懷疑這是對問題的直接回答。您可以將此視爲解決問題的替代方法。

我認爲可以考慮第二個文件作爲第一個文件的第二部分。通常在zip應用程序中,我們會看到一個巨大的文件被分成多個部分。如果打開第一部分,應用程序會自動考慮其他部分進一步處理。

我們可以在這裏模擬同樣的事情。正如@edg指出的那樣,修補文件系統將是一種方式。

15

花時間搞清楚涉及磁盤扇區洗牌和文件鏈操縱聰明的解決方案:2-4小時

時間花在獲取/寫軟件做就地複製和截斷:2-20小時

倍中位數$ 50 /小時程序員率:$ 400- $ 1200

性價比最高的1TB的USB驅動器的:理解短語 「機會成本」 $ 100- $ 200

能力:無價

1

效率不高,但我認爲可以做到。

以追加模式打開第一個文件,並將第二個文件中的塊複製到它,直到磁盤快滿。對於第二個文件的其餘部分,通過隨機訪問I/O將文件塊從停止位置複製到文件起始處。複製最後一個塊後截斷文件。重複,直到完成。

1

確定,理論上的娛樂,只要你保證不浪費你的時間其實這樣做:

  • 文件被存儲在磁盤碎片
  • 的片以鏈連接

所以,你可以通過級聯這些文件:

  • 最後一塊的第一個文件的鏈接到第一片的最後一個文件
  • 改變的第一個文件目錄項改變的最後一塊和文件大小
  • 除去最後文件
  • 清理的第一個文件的目錄項的最終OF-文件標記
  • 請注意,如果第一個文件的最後一部分只是部分填充,則必須將數據「向上」複製到最後一個文件的各個部分,以避免在文件中間出現垃圾。 @楔!]

這將是最佳效率:最小的改動,最小的複製,沒有備用的磁盤空間要求。

現在去購買一個USB驅動器;-)

1

顯然,經濟的答案是購買更多的存儲假設這是一個可能的答案。然而,它可能不是 - 嵌入式系統無法附加更多存儲空間,甚至無法訪問設備本身 - 比如說飛行中的空間探測器。

如果你有一個稀疏的文件系統,以前提出的基於稀疏文件系統的答案是好的(除了它的破壞性本質,如果出現問題!)。但是,如果你不這樣做呢?

從文件2的結尾開始,將塊複製到目標文件的起始位置,以便隨時撤消它們。在每個塊之後,將源文件截斷爲未複製的長度。對文件#1重複。

此時目標文件包含所有數據反向,源文件不見了。

從目標文件的末端和末尾讀取一個塊,將它們反轉並將它們寫入另一個來自的目標。用你的方式向內翻轉塊。

完成後,目標文件就是源文件的連接。不需要稀疏的文件系統,不需要搞亂文件系統。由於數據可以保存在內存中,因此可以在零字節處免費執行。

6

這是對我的first answer的輕微改進。

如果您有100MB空閒空間,請複製第二個文件中的最後100MB並創建第​​三個文件。截斷第二個文件,使其現在小100MB。重複這個過程直到第二個文件被完全分解成單個的100MB塊。

現在,每個100MB文件都可以附加到第一個文件,一次一個。

0

你可以這樣做:

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

,你可以根據你多少額外的磁盤空間有加1024,然後就重複,直到所有的字節都被移動。

這可能是做這(在開發時間上)

0

您可以通過壓縮整個文件系統來獲得空間的最快方式。我相信NTFS支持這一點,並且我確信有支持它的* nix文件系統的風格。在複製文件之後,您還可以獲得比開始時還剩餘更多磁盤空間的好處。

0

好的,稍微改變一下問題。有可能磁盤上還有其他你不需要的東西,但是你不知道它是什麼或者它在哪裏。如果你能找到它,你可以刪除它,然後也許你有足夠的額外空間。

爲了找到這些「腫瘤」,無論是一些大的腫瘤還是大量的小腫瘤,我都會使用一些小樣本程序。從目錄(或根目錄)的頂部開始,它會進行兩次傳遞。在第1遍中,它遍歷目錄樹,將所有文件的大小相加得到總共N個字節。在第2遍中,它再次走過目錄樹,假裝正在讀取每個文件。每次通過N/20字節時,它會打印出它正在「讀取」的文件的目錄路徑和名稱。所以最終結果是路徑名的20個深度樣本均勻分佈在目錄下的所有字節中。

然後,只要看看那些顯示很多你不需要的東西,然後去吹掉它。

(這是我使用的性能優化抽樣方法的空間當量)

2

如果該文件是高度可壓縮(即原木):

gzip file1 

gzip file2 

zcat file1 file2 | gzip > file3 

rm file1 

rm file2 

gunzip file3