`
javaboy2006
  • 浏览: 186314 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

多路归并排序

阅读更多
package merge;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * 
 * 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,
 * 需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。
 * 外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装人内存的部分,
 * 分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行归并排序。
 * 一般来说外排序分为两个步骤:预处理和合并排序。即首先根据内存的大小,将有n个记录的磁盘文件分批读入内存,采用有效的内存排序方法进行排序,将其预处理为若干个有序的子文件,这些有序子文件就是初始顺串,然后采用合并的方法将这些初始顺串逐趟合并成一个有序文件。
 * 
 * @author jia.hej
 *
 * @version $Id: MergeSort.java, v 0.1 2009-8-7 下午03:53:51 jia.hej Exp $
 */
public class MergeSort {

    /** 十 */
    private static long   TEN              = 10;
    /** 百 */
    private static long   HUNDRED          = 100;
    /** 千 */
    private static long   THOUSAND         = 1000;
    /** 万 */
    private static long   MILLION          = 10000;                 //1078  00:00:01 078
    /** 十万 */
    private static long   TEN_MILLION      = 100000;                //9656  00:00:09 656
    /** 百万 */
    private static long   HUNDRED_MILLION  = 1000000;               //93733  00:01:33 733
    /** 千万 */
    private static long   THOUSAND_MILLION = 10000000;              //970144  00:16:10 144
    /** 亿 */
    private static long   BILLION          = 100000000;
    /** 十亿 */
    private static long   TEN_BILLION      = 1000000000;
    /** 百亿 */
    private static long   HUNDRED_BILLION  = 10000000000l;
    /** 千亿 */
    private static long   THOUSAND_BILLION = 100000000000l;

    private static String INPUT_FILE       = "c:\\test\\input.txt";

    private static String OUTPUT_FILE      = "c:\\test\\output.txt";

    /** 拆分大小 */
    private static int    SPLIT_SIZE       = 10 * 10000;

    private static int    numSize;

    public static void main(String[] args) throws Exception {
        createDir("c:\\test");
        createFile(INPUT_FILE);
        numSize = createRandomNum(THOUSAND_MILLION);

        sortFile(INPUT_FILE);

        long beginTime = System.currentTimeMillis();
        System.out.println("begin=" + beginTime);

        //拆分文件
        splitFile(INPUT_FILE, numSize);

        List<String> splitFilePathList = new ArrayList<String>();
        File dir = new File("c:\\test\\temp");
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            splitFilePathList.add(file.getAbsolutePath());
        }
        //合并文件
        createFile(OUTPUT_FILE);
        mergeFile(splitFilePathList, OUTPUT_FILE);

        long endTime = System.currentTimeMillis();
        System.out.println("end=" + endTime);
        System.out.println("end-begin=" + (endTime - beginTime));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println(simpleDateFormat.format(endTime - beginTime));

        //删除拆分文件
        System.gc();
        Runtime.getRuntime().exec(new String[] { "cmd", "/c", "del", "c:\\test\\temp\\*.txt" });
    }

    private static void sortFile(String path) throws Exception {
        SortedSet<Integer> set = new TreeSet<Integer>();
        File file = new File(path);
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String value;
        while ((value = bufferedReader.readLine()) != null) {
            set.add(Integer.parseInt(value));
        }
        bufferedReader.close();
        fileReader.close();
        createFile("c:\\test\\input排序.txt");
        writeFile("c:\\test\\input排序.txt", set, false);
    }

    /**
     * 拆分文件
     * 
     * @param inputPath
     * @param numSize
     * @throws Exception
     */
    private static void splitFile(String inputPath, int numSize) throws Exception {
        File file = new File(inputPath);
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        SortedSet<Integer> set = new TreeSet<Integer>();
        String str;
        createDir("c:\\test\\temp");
        if (numSize > SPLIT_SIZE) {
            int count = 1;
            int fileNum = 1;
            while ((str = bufferedReader.readLine()) != null) {
                set.add(Integer.parseInt(str));
                //超过拆分数,写入子文件
                if (count >= SPLIT_SIZE) {
                    createFile("c:\\test\\temp\\" + fileNum + ".txt");
                    writeFile("c:\\test\\temp\\" + fileNum + ".txt", set, false);
                    set.clear();
                    count = 0;
                    fileNum++;
                }
                count++;//读取文件当前行数
            }
        }
        //总量未达到拆分数,写入子文件
        else {
            while ((str = bufferedReader.readLine()) != null) {
                set.add(Integer.parseInt(str));
            }
            createFile("c:\\test\\temp\\1.txt");
            writeFile("c:\\test\\temp\\1.txt", set, false);
        }
        if (bufferedReader != null) {
            bufferedReader.close();
        }
        if (fileReader != null) {
            fileReader.close();
        }
    }

    /**
     * 合并文件
     * 
     * <p>
     *    1.txt(1、3、5、7、9)和2.txt(6、8、9)<br/>
     *    首先1和6进入treeset。 <br/>
     *    输出1,发现是来自于1.txt的,再读入3,此时set中的元素是6和3。<br/> 
     *    输出3,发现还是来自于1.txt的,再读入5,此时set中的元素是6和5。 <br/>
     *    输出5,发现还是来自于1.txt的,再读入7,此时set中的元素是6和7。 <br/>
     *    输出6,发现来自于2.txt的,读入8,此时set中的元素是8和7。 <br/>
     *    输出7,发现来自于1.txt的,读入9,此时set中的元素是8和9。 <br/>
     *    输出8,发现来自于2.txt的,无法再读入9,此时set中的元素是9。<br/>
     *    输出9。
     * </p>
     * 
     * @param splitFilePathList
     * @param outputPath
     * @throws Exception
     */
    private static void mergeFile(List<String> splitFilePathList, String outputPath)
                                                                                    throws Exception {
        //fileInfo添加到set
        SortedSet<FileInfo> fileInfoSet = new TreeSet<FileInfo>(new FileInfoComparator());
        if (fileInfoSet.isEmpty()) {
            for (int i = 0; i < splitFilePathList.size(); i++) {
                File file = new File(splitFilePathList.get(i));
                FileReader fileReader = new FileReader(file);
                BufferedReader bufferedReader = new BufferedReader(fileReader);

                FileInfo fileInfo = new FileInfo();
                String splitFilePath = splitFilePathList.get(i);
                fileInfo.setFileNum(Integer.parseInt(splitFilePath.substring(splitFilePath
                    .lastIndexOf("\\") + 1, splitFilePath.indexOf(".txt"))));//文件号
                fileInfo.setReader(bufferedReader);//reader引用
                String value = bufferedReader.readLine();
                if (value != null) {
                    fileInfo.setValue(value);//当前值
                    fileInfo.setLineNum(fileInfo.getLineNum() + 1);//当前行号
                    fileInfoSet.add(fileInfo);
                }
            }
        }

        Set<Integer> valueSet = new LinkedHashSet<Integer>();
        boolean isSplit = false;
        int count = 1;
        //输出set元素
        while (!fileInfoSet.isEmpty()) {
            FileInfo currentFileInfo = fileInfoSet.first();
            valueSet.add(Integer.parseInt(currentFileInfo.getValue()));
            //拆分批量写入文件
            if (valueSet.size() >= SPLIT_SIZE) {
                writeFile(outputPath, valueSet, true);
                valueSet.clear();
                isSplit = true;
            }

            //clone fileInfo
            FileInfo nextFileInfo = new FileInfo();
            nextFileInfo.setFileNum(currentFileInfo.getFileNum());
            nextFileInfo.setLineNum(currentFileInfo.getLineNum());
            nextFileInfo.setValue(currentFileInfo.getValue());
            nextFileInfo.setReader(currentFileInfo.getReader());

            boolean isSuccess = nextFileInfo.readNextValue();

            //未到文件末尾,set中fileInfo重新排序
            if (isSuccess) {
                if (fileInfoSet.remove(currentFileInfo)) {
                    fileInfoSet.add(nextFileInfo);
                }
            }
            //已到文件末尾,从set中移除该fileInfo
            else {
                fileInfoSet.remove(currentFileInfo);
            }

            System.out.println("----- MergeFile:" + count++ + " -----");
            System.out.println("fileNum=" + currentFileInfo.getFileNum());
            System.out.println("lineNum=" + currentFileInfo.getLineNum());
            System.out.println("value=" + currentFileInfo.getValue());
            System.out.println("----------------------------");
        }

        //从未拆分过则一次性写入文件
        if (valueSet.size() > 0 && valueSet.size() < SPLIT_SIZE && !isSplit) {
            writeFile(outputPath, valueSet, false);
        }
        //曾拆分过剩余部分写入文件
        else if (valueSet.size() > 0 && valueSet.size() < SPLIT_SIZE && isSplit) {
            writeFile(outputPath, valueSet, true);
        }
    }

    /**
     * 生成随机数
     * 
     * @param numSize
     * @return
     * @throws Exception
     */
    private static int createRandomNum(long numSize) throws Exception {
        Set<Integer> set = new LinkedHashSet<Integer>();
        int count = 0;
        boolean isSplit = false;
        while (count < numSize) {
            int num = (int) (Math.random() * numSize + 1);
            if (set.add(num)) {
                count++;
            }
            //拆分批量写入文件
            if (set.size() >= SPLIT_SIZE) {
                writeFile(INPUT_FILE, set, true);
                set.clear();
                isSplit = true;
            }
        }

        //从未拆分过则一次写入文件
        if (set.size() > 0 && set.size() < SPLIT_SIZE && !isSplit) {
            writeFile(INPUT_FILE, set, false);
        }
        //曾拆分过剩余部分写入文件
        else if (set.size() > 0 && set.size() < SPLIT_SIZE && isSplit) {
            writeFile(INPUT_FILE, set, true);
        }
        return count;
    }

    private static void createDir(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) {
            if (dir.mkdir()) {
                System.out.println(dir.getName() + " is create.");
            }
        }
    }

    private static void createFile(String path) throws Exception {
        File file = new File(path);
        if (!file.exists()) {
            if (file.createNewFile()) {
                System.out.println(file.getName() + " is create.");
            }
        }
    }

    private static void writeFile(String path, Set<Integer> set, boolean isAppend) throws Exception {
        File file = new File(path);
        FileWriter fileWriter = new FileWriter(file, isAppend);// 第二个参数表示:是否为追加模
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()) {
            bufferedWriter.write(iterator.next().toString());
            bufferedWriter.newLine();
        }
        bufferedWriter.flush();
        if (bufferedWriter != null) {
            bufferedWriter.close();
        }
        if (fileWriter != null) {
            fileWriter.close();
        }
    }
}

package merge;

import java.io.BufferedReader;

/**
 * 
 * 文件信息
 * 
 * @author jia.hej
 *
 * @version $Id: FileInfo.java, v 0.1 2009-8-1 上午02:11:30 jia.hej Exp $
 */
public class FileInfo {

    /**
     * 文件号
     */
    private int            fileNum;

    /**
     * 当前行号
     */
    private int            lineNum = 0;

    /**
     * 当前值
     */
    private String         value;

    /**
     * BufferedReader引用
     */
    private BufferedReader reader;

    public boolean readNextValue() throws Exception {
        String value;
        if ((value = this.reader.readLine()) != null) {
            this.value = value;
            this.lineNum++;
            return true;
        } else {
            this.reader.close();
            return false;
        }
    }

    public int getFileNum() {
        return fileNum;
    }

    public void setFileNum(int fileNum) {
        this.fileNum = fileNum;
    }

    public int getLineNum() {
        return lineNum;
    }

    public void setLineNum(int lineNum) {
        this.lineNum = lineNum;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public BufferedReader getReader() {
        return reader;
    }

    public void setReader(BufferedReader reader) {
        this.reader = reader;
    }
}

package merge;

import java.util.Comparator;

/**
 * 
 * 文件比较器
 * 
 * @author jia.hej
 *
 * @version $Id: FileInfoComparator.java, v 0.1 2009-8-7 下午01:42:05 jia.hej Exp $
 */
public class FileInfoComparator implements Comparator<FileInfo> {

    public int compare(FileInfo o1, FileInfo o2) {
        if (Integer.parseInt(o1.getValue()) != Integer.parseInt(o2.getValue())) {
            return Integer.parseInt(o1.getValue()) - Integer.parseInt(o2.getValue());
        }
        //如果存在重复值则使用文件号比较
        else {
            return o1.getFileNum() - o2.getFileNum();
        }
    }

}



重写的第二版
package merge;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * 
 * @author jia.hej
 * @version $Id: MergeSort.java, v 0.1 2017-5-6 上午12:56:01 jia.hej Exp $
 */
public class MergeSort {

    /** 十 */
    private static long   TEN              = 10;
    /** 百 */
    private static long   HUNDRED          = 100;
    /** 千 */
    private static long   THOUSAND         = 1000;
    /** 万 */
    private static long   MILLION          = 10000;                 //1078  00:00:01 078
    /** 十万 */
    private static long   TEN_MILLION      = 100000;                //9656  00:00:09 656
    /** 百万 */
    private static long   HUNDRED_MILLION  = 1000000;               //93733  00:01:33 733
    /** 千万 */
    private static long   THOUSAND_MILLION = 10000000;              //970144  00:16:10 144
    /** 亿 */
    private static long   BILLION          = 100000000;
    /** 十亿 */
    private static long   TEN_BILLION      = 1000000000;
    /** 百亿 */
    private static long   HUNDRED_BILLION  = 10000000000l;
    /** 千亿 */
    private static long   THOUSAND_BILLION = 100000000000l;

    private static String INPUT_FILE       = "c:\\test\\input.txt";

    private static String OUTPUT_FILE      = "c:\\test\\output.txt";

    /** 拆分大小 */
    private static int    SPLIT_SIZE       = 1000;

    public static void main(String[] args) throws Exception {
        createDir("c:\\test");
        createFile(INPUT_FILE);
        int numberSize = createRandomNum(TEN_MILLION);

        long beginTime = System.currentTimeMillis();

        //文件拆分
        splitFile(INPUT_FILE, numberSize);

        createDir("c:\\test\\sort");
        List<String> splitFilePathList = new ArrayList<String>();
        File dir = new File("c:\\test\\temp");
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            splitFilePathList.add(file.getAbsolutePath());

            //文件排序
            sortFile(file.getAbsolutePath());
        }

        //文件合并
        createFile(OUTPUT_FILE);
        mergeFile(splitFilePathList, OUTPUT_FILE);

        System.out.println("begin=" + beginTime);
        long endTime = System.currentTimeMillis();
        System.out.println("end=" + endTime);
        System.out.println("总耗时=" + ((endTime - beginTime) / 1000) + "s");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println(simpleDateFormat.format(endTime - beginTime));

        //删除临时拆分文件
        System.gc();
        Runtime.getRuntime().exec(new String[] { "cmd", "/c", "del", "c:\\test\\temp\\*.txt" });
        Runtime.getRuntime().exec(new String[] { "cmd", "/c", "del", "c:\\test\\sort\\*.txt" });
    }

    private static void sortFile(String path) throws Exception {
        SortedSet<Integer> set = new TreeSet<Integer>();
        File file = new File(path);
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String value;
        while ((value = bufferedReader.readLine()) != null) {
            set.add(Integer.parseInt(value));
        }
        bufferedReader.close();
        fileReader.close();
        createFile("c:\\test\\sort\\" + file.getName());
        writeFile("c:\\test\\sort\\" + file.getName(), set, false);
    }

    /**
     * 拆分文件
     * 
     * @param inputPath
     * @param numSize
     * @throws Exception
     */
    private static void splitFile(String inputPath, int numberSize) throws Exception {
        File file = new File(inputPath);
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        SortedSet<Integer> set = new TreeSet<Integer>();
        String str;
        createDir("c:\\test\\temp");

        if (numberSize > SPLIT_SIZE) {
            int count = 1;
            int fileNum = 1;
            while ((str = bufferedReader.readLine()) != null) {
                set.add(Integer.parseInt(str));
                //超过拆分数,写入子文件
                if (count >= SPLIT_SIZE) {
                    createFile("c:\\test\\temp\\" + fileNum + ".txt");
                    writeFile("c:\\test\\temp\\" + fileNum + ".txt", set, false);
                    set.clear();
                    count = 0;
                    fileNum++;
                }
                count++;//读取文件当前行数
            }
        }
        //总量未达到拆分数,写入子文件
        else {
            while ((str = bufferedReader.readLine()) != null) {
                set.add(Integer.parseInt(str));
            }
            createFile("c:\\test\\temp\\1.txt");
            writeFile("c:\\test\\temp\\1.txt", set, false);
        }
        if (bufferedReader != null) {
            bufferedReader.close();
        }
        if (fileReader != null) {
            fileReader.close();
        }
    }

    /**
     * 合并文件
     * 
     * <p>
     *    1.txt(1、3、5、7、9)和2.txt(6、8、9)<br/>
     *    首先1和6进入treeset。 <br/>
     *    输出1,发现是来自于1.txt的,再读入3,此时set中的元素是6和3。<br/> 
     *    输出3,发现还是来自于1.txt的,再读入5,此时set中的元素是6和5。 <br/>
     *    输出5,发现还是来自于1.txt的,再读入7,此时set中的元素是6和7。 <br/>
     *    输出6,发现来自于2.txt的,读入8,此时set中的元素是8和7。 <br/>
     *    输出7,发现来自于1.txt的,读入9,此时set中的元素是8和9。 <br/>
     *    输出8,发现来自于2.txt的,无法再读入9,此时set中的元素是9。<br/>
     *    输出9。
     * </p>
     * 
     * @param splitFilePathList
     * @param outputPath
     * @throws Exception
     */
    private static void mergeFile(List<String> splitFilePathList, String outputPath)
                                                                                    throws Exception {
        //按拆分文件数初始化map
        Map<Integer, FileInfo> valueFileMap = new HashMap<Integer, FileInfo>();
        for (int i = 0; i < splitFilePathList.size(); i++) {
            File file = new File(splitFilePathList.get(i));
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);

            FileInfo fileInfo = new FileInfo();
            String splitFilePath = splitFilePathList.get(i);
            fileInfo.setFileNo(Integer.parseInt(splitFilePath.substring(
                splitFilePath.lastIndexOf("\\") + 1, splitFilePath.indexOf(".txt"))));//文件号
            fileInfo.setReader(bufferedReader);//reader引用
            String value = bufferedReader.readLine();
            if (value != null) {
                fileInfo.setCurrentValue(value);//当前值
                fileInfo.setCurrentLineNo(fileInfo.getCurrentLineNo() + 1);//当前行号
                valueFileMap.put(Integer.parseInt(value), fileInfo);
            }
        }

        File outputFile = new File(outputPath);
        FileWriter outputFileWriter = new FileWriter(outputFile, true);// 第二个参数表示:是否为追加模式
        BufferedWriter outputBufferedWriter = new BufferedWriter(outputFileWriter);

        //按文件行号横向遍历
        for (int i = 0; i < splitFilePathList.size() * SPLIT_SIZE; i++) {
            //查找最小值
            Integer minValue = Integer.MAX_VALUE;
            for (Integer currentValue : valueFileMap.keySet()) {
                if (currentValue.intValue() < minValue) {
                    minValue = currentValue.intValue();
                }
            }

            //最小值追加到输出文件
            Set<Integer> tempValueSet = new LinkedHashSet<Integer>();
            tempValueSet.add(minValue);
            writeFile(outputBufferedWriter, tempValueSet);

            //命中FileInfo读指针后移
            FileInfo currentFileInfo = valueFileMap.get(minValue);

            System.out.println("----- MergeFile:" + (i + 1) + " -----");
            System.out.println("fileNo=" + currentFileInfo.getFileNo());
            System.out.println("currentLineNo=" + currentFileInfo.getCurrentLineNo());
            System.out.println("currentValue=" + currentFileInfo.getCurrentValue());
            System.out.println("----------------------------");

            FileInfo nextFileInfo = new FileInfo();
            nextFileInfo.setFileNo(currentFileInfo.getFileNo());
            nextFileInfo.setCurrentLineNo(currentFileInfo.getCurrentLineNo());
            nextFileInfo.setReader(currentFileInfo.getReader());

            valueFileMap.remove(minValue);

            //读指针未到文件尾
            if (nextFileInfo.readNextValue()) {
                valueFileMap.put(Integer.parseInt(nextFileInfo.getCurrentValue()), nextFileInfo);
            } else {
                nextFileInfo.closeReader();
            }
        }

        if (outputBufferedWriter != null) {
            outputBufferedWriter.close();
        }
        if (outputFileWriter != null) {
            outputFileWriter.close();
        }
    }

    /**
     * 生成随机数
     * 
     * @param numberSize
     * @return
     * @throws Exception
     */
    private static int createRandomNum(long numberSize) throws Exception {
        int count = 0;
        Set<Integer> set = new LinkedHashSet<Integer>();

        while (count < numberSize) {
            int num = (int) (Math.random() * numberSize);
            if (set.add(num)) {
                count++;
            }
        }

        writeFile(INPUT_FILE, set, true);
        return count;
    }

    private static void createDir(String dirPath) {
        File dir = new File(dirPath);
        if (dir.exists()) {
            dir.delete();
        }

        if (dir.mkdir()) {
            System.out.println("[" + dir.getName() + " dir is create]");
        }
    }

    private static void createFile(String path) throws Exception {
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }

        if (file.createNewFile()) {
            System.out.println("[" + file.getName() + " file is create]");
        }
    }

    private static void writeFile(String path, Set<Integer> set, boolean isAppend) throws Exception {
        File file = new File(path);
        FileWriter fileWriter = new FileWriter(file, isAppend);// 第二个参数表示:是否为追加模式
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()) {
            bufferedWriter.write(iterator.next().toString());
            bufferedWriter.newLine();
        }
        bufferedWriter.flush();
        if (bufferedWriter != null) {
            bufferedWriter.close();
        }
        if (fileWriter != null) {
            fileWriter.close();
        }
    }

    private static void writeFile(BufferedWriter bufferedWriter, Set<Integer> set) throws Exception {
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()) {
            bufferedWriter.write(iterator.next().toString());
            bufferedWriter.newLine();
        }
        bufferedWriter.flush();
    }

}

package merge;

import java.io.BufferedReader;
import java.io.IOException;

/**
 * 
 * 文件信息
 * 
 * @author jia.hej
 * @version $Id: FileInfo.java, v 0.1 2017-5-6 上午12:56:01 jia.hej Exp $
 */
public class FileInfo {

    /**
     * 文件号
     */
    private int            fileNo        = 0;

    /**
     * 当前行号
     */
    private int            currentLineNo = 0;

    /**
     * 当前值
     */
    private String         currentValue;

    /**
     * BufferedReader引用
     */
    private BufferedReader reader;

    public boolean readNextValue() throws Exception {
        if (reader == null) {
            return false;
        }

        String value;
        if ((value = this.reader.readLine()) != null) {
            this.currentValue = value;
            this.currentLineNo++;
            return true;
        } else {
            this.reader.close();
            this.reader = null;
            return false;
        }
    }

    public void closeReader() throws IOException {
        if (reader != null) {
            reader.close();
        }
    }

    public int getFileNo() {
        return fileNo;
    }

    public void setFileNo(int fileNo) {
        this.fileNo = fileNo;
    }

    public int getCurrentLineNo() {
        return currentLineNo;
    }

    public void setCurrentLineNo(int currentLineNo) {
        this.currentLineNo = currentLineNo;
    }

    public String getCurrentValue() {
        return currentValue;
    }

    public void setCurrentValue(String currentValue) {
        this.currentValue = currentValue;
    }

    public BufferedReader getReader() {
        return reader;
    }

    public void setReader(BufferedReader reader) {
        this.reader = reader;
    }

}
分享到:
评论

相关推荐

    数据库系统实现-两阶段多路归并排序算法的C实现

    两阶段多路归并排序算法是一种常用于数据库管理系统中的高效排序方法。本文将深入探讨这个算法,并结合C语言的实现来阐述其工作原理。 首先,我们要理解什么是归并排序。归并排序是一种基于分治思想的排序算法,它...

    外排序(磁盘排序)之多路归并排序的简单实现

    ### 外排序(磁盘排序)之多路归并排序的简单实现 #### 知识点概述 在计算机科学领域,排序算法是数据处理的重要组成部分。对于内存足够存放所有待排序元素的情况,我们通常采用诸如快速排序、堆排序等内部排序方法...

    数据库系统实现两阶段多路归并排序算法的C实现.docx

    数据库系统实现两阶段多路归并排序算法的C实现 数据库系统实现两阶段多路归并排序算法的C实现是指使用C语言实现两阶段多路归并排序算法,以解决大规模数据库排序问题。该算法分为两个阶段:Phase 1和Phase 2。Phase...

    kgb.rar_多路归并排序_多路排序

    多路归并排序算法,主要针对于海量数据排序,代码中有注释。

    二阶段多路归并排序代码

    数据库系统实现中二阶段多路归并排序的实现 C代码 生成文件时需要很长时间 仅仅是测试代码

    外排序之多路归并的java实现

    外排序--基于败者树的多路归并排序算法的java实现

    Python文件操作及多路归并排序

    文件归并排序 命令行说明: sort.py -i &lt;input_filename&gt; -o &lt;output_filename&gt; [-d ] [-c ] [-s ] [-t ] -i 输入源文件名 -o 输出目标文件名,如果未指定,则结果覆盖到源文件 -d 可选项,文件文本行的列分隔符,...

    三路归并_C语言_三路归并排序_三路归并_

    **三路归并排序**是一种高效的排序算法,尤其在处理含有大量重复元素的序列时表现优秀。该算法基于归并排序的思想,但将其分为三个部分处理,而不是传统的两个部分。在本文中,我们将深入探讨三路归并排序的原理、...

    基于C语言实现的多路归并排序算法源代码+详细注释

    基于C语言实现的多路归并排序算法源代码+详细注释

    二路归并排序

    MergeSort 函数是二路归并排序的主函数,它将待排序的记录分成多个部分,然后对每个部分进行排序,最后将已排序的部分合并成一个有序的序列。 实验结果 实验结果显示了二路归并排序的过程,每一趟的排序结果都会被...

    C语言二路归并排序算法

    ### C语言二路归并排序算法 #### 概述 归并排序是一种高效的排序算法,其基本思想是采用分治法(Divide and Conquer),将一个数组分成两个子数组,然后递归地对这两个子数组进行排序,最后将两个有序的子数组合并...

    理解归并排序的算法思想及其算法设计

    它可以分为多路归并排序和两路归并排序两种,既可以用于内排序也可以用于外排序。 2. 归并排序的算法思路 归并排序的算法思路是将初始序列看成 n 个长度为 1 的有序序列,进行两两归并,得到 [n/2] 个长度为 2 的...

    多路归并之根号n排序

    然而,“多路归并之根号n排序”是对传统归并排序的一种优化,它借鉴了二路归并的思想,但不局限于每次划分成两部分,而是选择将数组划分为根号n个子数组。这种优化的主要原因是,当数据量非常大时,每次划分成两部分...

    2-路归并排序,写一个算法在链表结构上实现这一策略

    2-路归并排序是一种高效的排序算法,特别适用于大数据量的场景。它的基本思想是将待排序的序列分成两个子序列,分别进行排序,然后将这两个已排序的子序列合并成一个有序序列。在这个过程中,通常会使用到链表结构,...

    多路归并外排序的C/C++完整实现(数据自动随机生成,菜单化,很容易操作)

    多路归并外排序是一种处理大数据量排序的算法,尤其适用于内存不足以一次性装载所有数据的情况。在C/C++中实现这种排序方法,需要理解其基本原理,并结合编程技巧来完成。下面将详细介绍多路归并外排序的过程以及...

    归并排序,基数排序算法比较

    总结来说,归并排序适用于大型数据集,尤其是当稳定性很重要时,而基数排序则在处理整数且位数不太多的数据时表现出色,因为它不需要任何比较操作。在实际应用中,选择哪种排序算法取决于具体的需求,如数据规模、...

    常用排序算法源程序

    这里我们主要探讨四个常见的排序算法:快速排序、堆排序、二路归并排序(包括递归和非递归实现)以及多路归并排序。这些算法在实际应用中具有广泛的重要性,尤其是在大数据处理和性能优化方面。 1. **快速排序...

    多路归并算法

    多路归并算法是一种高效的排序方法,尤其在处理大量数据时表现出色。它基于分治策略,将大问题分解为小问题,然后合并这些小问题的解以得到最终的解决方案。在本例中,我们使用C#编程语言来实现这个算法,对文件中的...

Global site tag (gtag.js) - Google Analytics