讀取海量數據到文件並拆分排序

1、從mysql讀取海量數據,將其寫入到文件中,並拆分文件進行排序。下面是測試用例。代碼展示:

/**
 * Created by xxx on 2016/8/29.
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

public class CombinationSortWrite {
    /**
     * 大數據排序合併
     * 從msql數據庫讀取數據,寫入文件,並將文件拆分
     */
    public static void main(String[] args) throws IOException {
        // 寫入文件的路徑
        String filePath = "D:\\456";
        // 切分文件的路徑
        String sqlitFilePath = "D:\\456\\123";

        //數據的個數
        int CountNumbers = 1000000;

        //子文件的個數
        int CountFile = 10;

        //精度
        int countAccuracy = 30*CountFile;

        long startNumber=System.currentTimeMillis();
        // 寫入大數據文件
        WriteData(filePath,CountNumbers);
        System.out.println("存儲完畢");

        // 將大數據文件切分到另外的十個小文件中
        sqlitFileDate(filePath, sqlitFilePath,CountFile);
        System.out.println("文件切割完畢!");

        // 把每個文件的數據進行排序
        singleFileDataSort(sqlitFilePath,CountFile);
        System.out.println("每個子文件排序完畢!");

        //精度調整,十個文件數據進行比較整合
        deathDataFile(filePath,sqlitFilePath,countAccuracy,CountFile);
        System.out.println("整合完畢");
        long stopNumber=System.currentTimeMillis();
        System.out.println("耗時"+(stopNumber-startNumber)/1000+"毫秒");
    }

    // 寫入大數據文件
    public static void WriteData(String path,int CountNumbers) throws IOException {
        path = path + "\\12114.txt";
        FileWriter fs = new FileWriter(path);
        BufferedWriter fw = new BufferedWriter(fs);
        for (int i = 0; i < CountNumbers; i++) {
            fw.write(new Random().nextInt(Integer.MAX_VALUE) + "\r\n");
        }
        fw.close();
        fs.close();

    }

    // 將大數據文件切分到另外的十個小文件中
    public static void sqlitFileDate(String filepath, String sqlitPath,
                                     int CountFile) throws IOException {
        FileWriter fs = null;
        BufferedWriter fw=null;
        FileReader fr = new FileReader(filepath + "\\12114.txt");
        BufferedReader br = new BufferedReader(fr); // 讀取獲取整行數據

        int i = 1;
        LinkedList WriterLists=new LinkedList();    //初始化文件流對象集合
        LinkedList fwLists=new LinkedList();
        for (int j = 1; j <= CountFile; j++) {

            //聲明對象
            fs = new FileWriter(sqlitPath + "\\12" + j + ".txt",false);
            fw=new BufferedWriter(fs);

            //將對象裝入集合
            WriterLists.add(fs);
            fwLists.add(fw);
        }
        //判斷是文件流中是否還有數據返回
        while (br.ready()) {
            int count=1;//初始化第一文件流
            for (Iterator iterator = fwLists.iterator(); iterator.hasNext();) {
                BufferedWriter type = (BufferedWriter) iterator.next();
                if(i==count)//判斷輪到第幾個文件流寫入數據了
                {
                    //寫入數據,跳出,進行下一個文件流,下一個數據的寫入
                    type.write(br.readLine() + "\r\n");
                    break;
                }
                count++;
            }
            //判斷是否到了最後一個文件流了
            if (i >= CountFile) {
                i = 1;
            } else
                i++;
        }
        br.close();
        fr.close();
        for (Iterator iterator = fwLists.iterator(); iterator.hasNext();) {
            BufferedWriter object = (BufferedWriter) iterator.next();
            object.close();
        }
        //遍歷關閉所有子文件流
        for (Iterator iterator = WriterLists.iterator(); iterator.hasNext();) {
            FileWriter object = (FileWriter) iterator.next();
            object.close();
        }
    }

    // 把每個文件的數據進行排序
    public static void singleFileDataSort(String path1,int CountFile) throws IOException {
        LinkedList nums = null;
        for (int i = 1; i <= CountFile; i++) {
            nums = new LinkedList();
            String path = path1 + "\\12" + i + ".txt";
            try {
                FileReader fr = new FileReader(path);
                BufferedReader br = new BufferedReader(fr);
                while (br.ready()) {
                    // 將讀取的單個數據加入到集合裏面
                    nums.add(Integer.parseInt(br.readLine()));
                }
                // 對集合進行排序
                Collections.sort(nums);

                // 將排序好的數據寫入源文件
                numberSort(nums, path);
                br.close();
                fr.close();
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 對每個文件數據進行排序,再寫入源文件
    public static void numberSort(LinkedList list, String path) {
        try {
            FileWriter fs = new FileWriter(path);
            BufferedWriter fw=new BufferedWriter(fs);
            for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                Object object = (Object) iterator.next();
                fw.write(object + "\r\n");
            }
            fw.close();
            fs.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 文件數據最終整合(精度調整)
    public static void deathDataFile(String filepath, String sqlitFilePath1,
                   int countAccuracy, int CountFile) throws IOException {
        LinkedList nums = new LinkedList();//添加數據,進行排序
        Object temp = null; // 記錄每次排序剩下的最後一個數字
        boolean ispass = false;
        LinkedList ispasses = null;//記錄數據文件的狀態信息
        FileWriter fs = new FileWriter(filepath + "\\Sort.txt", false);//創建文件流,以便整合的數據寫入
        BufferedWriter bw=new BufferedWriter(fs);
        FileReader fr = null; //聲明讀取文件流
        BufferedReader br = null; //聲明BufferedReader
        LinkedList WriterLists = new LinkedList(); // 初始化文件流對象集合
        LinkedList WriterListFile = new LinkedList();
        for (int j = 1; j <= CountFile; j++) {

            // 聲明對象,開啓所有子文件流訪問所有子文件的數據
            fr = new FileReader(sqlitFilePath1 + "\\12" + j + ".txt");

            //開啓所有BufferedReader,方便下次的整行的讀取
            br = new BufferedReader(fr);

            // 將所有 FileReader對象裝入集合
            WriterListFile.add(fr);

            // 將所有 BufferedReader對象裝入集合
            WriterLists.add(br);
        }

        for (;;) {

            // 將十個源文件的是否有數據情況存入集合,以方便後面做判斷
            ispasses = new LinkedList();

            // 分別讀取十個源文件的單個數據
            for (Iterator iterator = WriterLists.iterator(); iterator.hasNext();) {
                BufferedReader object = (BufferedReader) iterator.next();
                Object obj = null;
                while (object.ready()) {
                    //添加所有文件流的每次的數據
                    nums.add(Integer.parseInt(object.readLine().toString()));
                    break;
                }
                if (object.ready() == false)
                    ispasses.add("true");           //將各文件中的數據狀態存入集合中
            }

            // 決斷是否是第一次進來
            if (nums.size() % countAccuracy == 0 && ispass == false) {

                // 對集合進行排序
                Collections.sort(nums);

                // 接收最大的數據,其它的數據寫入總排序文件
                temp = numberSortData(nums, filepath, false, countAccuracy, bw);

                //重新初始化集合
                nums = new LinkedList();

                // 添加上一組比較剩下的數據
                nums.add(temp);
                ispass = true;

                // 記錄源文件的數據數量,以便下次的遍歷
                continue;
            }
            if (ispass) {
                if (nums.size() % countAccuracy == 1 && nums.size() > 1) {
                    // 對集合進行排序
                    Collections.sort(nums);

                    // 接收最大的數據,其它的數據寫入總排序文件
                    temp = numberSortData(nums, filepath, true, countAccuracy,
                            bw);
                    nums = new LinkedList();
                    nums.add(temp);
                    continue;
                }

            }
            // 記錄下一組數據的位置

            // 判斷是不是十個文件都沒有數據
            if (ispasses.size() == CountFile) {
                Collections.sort(nums);
                temp = numberSortData(nums, filepath, true, countAccuracy, bw);
                nums = new LinkedList();
                break;
            }
        }

        bw.close();
        //關閉寫入流
        fs.close();

        //關閉所有的BufferedReader
        for (Iterator iterator = WriterLists.iterator(); iterator.hasNext();) {
            BufferedReader object2 = (BufferedReader) iterator.next();
            object2.close();
        }

        //關閉所有的FileReader
        for (Iterator iterator = WriterListFile.iterator(); iterator.hasNext();) {
            FileReader object = (FileReader) iterator.next();
            object.close();
        }
    }

    // 對數據進行排序,寫入最終文件中(精度調整)
    public static Object numberSortData(LinkedList list, String filePath,
               boolean ispass, int countAccuracy,BufferedWriter fs) {
        Object temp = 0;//記錄最後一個值
        int tempCount = 0;//記錄寫入的數據位置
        try {
            for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                Object object = (Object) iterator.next();

                // 判斷是否是最後一個數
                if (tempCount == list.size() - 1) {
                    // 判斷集合裏面不足一百個數了
                    if (list.size() < countAccuracy + 1 && ispass) {
                        temp = null;
                    } else {
                        temp = object;
                        break;
                    }
                }

                // 寫入數據源
                fs.write(object + "\r\n");

                // 記錄數據的下標
                tempCount++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return temp;
    }
}
發佈了182 篇原創文章 · 獲贊 106 · 訪問量 60萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章