天天看點

Java大檔案排序(有手就能學會)

背景

如果你的機兒記憶體隻有8個G,現在要對一個10個G的檔案進行排序,嘤嘤嘤。

思路

這是小白最能了解的一種方案,我們先把10個G大檔案分成5個2G的小檔案

假設原檔案:2 15 4 18 1 9 7 12 6 5 8 4 7 16 3

小檔案一:2 15 4

小檔案二:18 1 9

小檔案三:7 12 6

小檔案四:5 8 4

小檔案五:7 16 3

對每個小檔案進行排序,這個就很多方法了,你可以直接讀到記憶體進行排序,排完了再寫回;

小檔案一:2 4 15

小檔案二:1 9 18

小檔案三:6 7 12

小檔案四:4 5 8

小檔案五:3 7 16

5個小檔案都排序好了後,我們依次從5個小檔案中讀取第一個元素,5個元素比較,選擇最小的值min,建立一個檔案,将min寫入新檔案

min(2 1 6 4 3)=1

存入LinkedList,此時LinkedList值為{1}

繼續從小檔案二中讀取下一個元素9

min(2 9 6 4 3)=2

存入LinkedList,此時LinkedList值為{1,2}

繼續從小檔案一中讀取下一個元素4

min(4 9 6 4 3)=3

存入LinkedList,此時LinkedList值為{1,2,3}

繼續從小檔案五中讀取下一個元素7

min(4 9 6 4 7)=4

存入LinkedList,此時LinkedList值為{1,2,3,4}

繼續從小檔案一中讀取下一個元素15

min(15 9 6 4 7)=4

存入LinkedList,此時LinkedList值為{1,2,3,4,4}

繼續從小檔案四中讀取下一個元素5

min(15 9 6 5 7)=5

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5}

繼續從小檔案四中讀取下一個元素8

min(15 9 6 8 7)=6

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6}

繼續從小檔案三中讀取下一個元素7

min(15 9 7 8 7)=7

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7}

繼續從小檔案三中讀取下一個元素12

min(15 9 12 8 7)=7

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7}

繼續從小檔案五中讀取下一個元素16

min(15 9 12 8 16)=8

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7,8}

小檔案四讀取完畢

min(15 9 12 16)=9

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7,8,9}

繼續從小檔案二中讀取下一個元素18

min(15 18 12 16)=12

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7,8,9,12}

小檔案三讀取完畢

min(15 18 16)=15

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7,8,9,12,15}

小檔案一讀取完畢

min(18 16)=16

存入LinkedList,此時LinkedList值為{1,2,3,4,4,5,6,7,7,8,9,12,15,16}

小檔案五讀取完畢

min(18)=18

小檔案二讀取完畢

存入LinkedList,最終LinkedList值為{1,2,3,4,4,5,6,7,7,8,9,12,15,16,18}

注意,這裡是為了示範友善,便于小白了解過程,每次直接從檔案中讀取一個,實際操作中我們不可能每次都隻讀取一個,IO操作是很耗時的,也不用每次隻對比5個,是以

優化

為了避免頻繁IO,我們可以依次從每個小檔案中讀取一部分到記憶體,比如讀取每個小檔案的前1000條(讀取的數量視情況而定,總之為了避免io,最好是在伺服器頂得住的情況下盡量多讀取一些到記憶體,因為一次記憶體操作和一次io操作耗時比起來幾乎可以忽略),讀取到記憶體後,用5個linkedList來接收,,我們對這5000條資料在記憶體中進行排序,排序算法自選,排好序寫入新檔案;寫完後清空記憶體中的5000條資料,繼續從每個新檔案中讀取一部分到記憶體,比如這次讀取每個小檔案的1001-2000條,以此類推…skr

ok我話講完