Demo

View Code
package me.xuzs.db;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FileDb {

    private static String FILE_ROOT = "D:/filedb/";
    private static String FILE_EXT = ".txt";
    private static int PAGE_SIZE = 10;

    public static void main(String[] args) {
        int limit = 25;
        int offset = 1;
        // int totalCount = queryCountByField("user");
        // System.out.println("记录总数: " + totalCount);
        List<String> dataList = queryList("other", limit, offset);
        // System.out.println("limit: " + limit + ", offset: " + offset);
         System.out.println(dataList);
//        insertData("other", dataList);

    }

    /**
     * 根据字段名查询数据所在路径
     * 
     * @param create
     * @return
     */
    public static File queryFilePathByFieldName(String field, boolean create) {
        String filePathStr = FILE_ROOT + field + File.separator;
        File filePath = new File(filePathStr);
        if (!filePath.exists() || !filePath.isDirectory()) {
            if (!create) {
                throw new IllegalArgumentException("字段不存在!");
            }
            filePath.mkdir();
        }
        return filePath;
    }

    /**
     * 返回指定记录的条数
     * 
     * @param field
     * @return
     */
    public static int queryCountByField(String field) {
        int totalRecord = 0;
        File filePath = queryFilePathByFieldName(field, false);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        Arrays.sort(fileNames);
        // 最新文件的文件名
        String lastFilePath = filePath.getAbsolutePath() + File.separator
                + fileNames[fileCount - 1];
        totalRecord += PAGE_SIZE * (fileCount - 1);
        totalRecord += queryCountInFile(lastFilePath);
        return totalRecord;
    }

    /**
     * 查询当前文件中有几条记录
     * 
     * @param fileName
     * @return
     */
    public static int queryCountInFile(String fileStr) {
        int count = 0;
        try {
            RandomAccessFile file = new RandomAccessFile(fileStr, "r");
            while (file.readLine() != null) {
                count++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 查询指定文件中的指定记录
     * 
     * @param fileStr
     *            文件全路径
     * @param limit
     *            查询条数
     * @param offset
     *            查询偏移量
     * @param contentList
     *            查询后结果存入
     * @return 查询到的行数
     */
    public static int queryListInFile(String fileStr, int limit, int offset,
            List<String> contentList) {
        int addedCount = 0;
        try {
            RandomAccessFile file = new RandomAccessFile(fileStr, "r");
            skipLine(file, offset);
            for (int i = 0; i < limit; i++) {
                String content = file.readLine();
                if (content == null) {
                    System.err.println("超过记录总数!");
                    break;
                }
                contentList.add(content);
                addedCount++;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return 1;
        } catch (IOException e) {
            e.printStackTrace();
            return 1;
        }
        return addedCount;
    }

    public static List<String> queryList(String field, int limit, int offset) {
        List<String> contentList = new ArrayList<String>(PAGE_SIZE);
        File filePath = queryFilePathByFieldName(field, false);
        // 文件偏移量
        int fileIndex = offset / PAGE_SIZE;
        // 记录偏移量
        int recordOffset = offset % PAGE_SIZE;
        // 记录条数
        int recordLimit = 0;
        if(limit - offset + recordOffset < PAGE_SIZE){
            recordLimit = limit;
        }
        else recordLimit = PAGE_SIZE - recordOffset;
        
        String toReadFileStr = "";
        // 首先查询一把
        toReadFileStr = field + "_" + fileIndex + FILE_EXT;
        limit -= queryListInFile(filePath.getAbsolutePath() + File.separator
                + toReadFileStr, recordLimit, recordOffset, contentList);
        fileIndex++;
        // 循环寻找下一个文件
        while (limit / PAGE_SIZE > 0) {
            toReadFileStr = field + "_" + fileIndex + FILE_EXT;
            limit -= queryListInFile(filePath.getAbsolutePath()
                    + File.separator + toReadFileStr, PAGE_SIZE, 0, contentList);
            fileIndex++;
        }
        toReadFileStr = field + "_" + fileIndex + FILE_EXT;
        limit -= queryListInFile(filePath.getAbsolutePath() + File.separator
                + toReadFileStr, limit, 0, contentList);
        return contentList;
    }

    /**
     * 跳过指定文件的指定行数
     * 
     * @param file
     * @param lineCount
     * @return
     */
    public static boolean skipLine(RandomAccessFile file, int lineCount) {
        boolean success = true;
        for (int i = 0; i < lineCount; i++) {
            try {
                file.readLine();
            } catch (IOException e) {
                e.printStackTrace();
                success = false;
            }
        }
        return success;
    }

    public static boolean insertData(String field, List<String> dataList) {
        File filePath = queryFilePathByFieldName(field, true);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        String fileNameStr = "";
        File toInsert = null;
        if (fileCount < 1) {
            toInsert = createFile(field);
        } else {
            Arrays.sort(fileNames);
            fileNameStr = fileNames[fileCount - 1];
            toInsert = new File(filePath.getAbsolutePath() + File.separator
                    + fileNameStr);
        }
        int recordCount = queryCountInFile(toInsert.getAbsolutePath());
        int recorded = 0;
        try {
            FileWriter fileWriter = new FileWriter(toInsert, true);
            for (String data : dataList) {

                fileWriter.append(data + "\n");
                recorded++;
                if (recorded + recordCount == PAGE_SIZE) {
                    toInsert = createFile(field);
                    fileWriter.flush();
                    fileWriter = new FileWriter(toInsert, true);
                    recorded = 0;
                    recordCount = 0;
                }
            }
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    /**
     * 创建文件
     * 
     * @param filePathStr
     * @param fileNameStr
     * @return
     */
    private static File createFile(String fieldName) {
        File filePath = queryFilePathByFieldName(fieldName, false);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        File toCreate = new File(filePath.getAbsolutePath() + File.separator
                + fieldName + "_" + fileCount + FILE_EXT);
        try {
            toCreate.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return toCreate;
    }
}
modified
package me.xuzs.db;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class FileDb {

    public static final String NEXT_LINE = System.getProperty("line.separator");
    private static String FILE_ROOT = "D:/filedb/";
    private static String FILE_EXT = ".txt";
    private static String CONNECT_CHAR = "_";
    private static int PAGE_SIZE = 50;

    public static void main(String[] args) {
        String field = "user";
//        init(field, 2000);
        int limit = 2;
        int offset = 4;
        int totalCount = queryCountByField(field);
        System.out.println("记录总数: " + totalCount);
        List<String> dataList = queryList(field, limit, offset);
        System.out.println("limit: " + limit + ", offset: " + offset);
        System.out.println(dataList);
    }
    
    /**
     * 初始化字段
     * @param field
     * @param count
     */
    public static void init(String field, int count){
        List<String> dataList = new ArrayList<String>(PAGE_SIZE);
        for (int i = 1; i <= count; i++) {
            dataList.add(String.valueOf(i));
        }
        insertData(field, dataList);
    }
    
    /**
     * 插入数据到文件
     * @param field
     * @param dataList
     * @return
     */
    public static boolean insertData(String field, List<String> dataList) {
        File filePath = queryFilePathByFieldName(field, true);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        String fileNameStr = "";
        File toInsert = null;
        if (fileCount < 1) {
            toInsert = createFile(field);
        } else {
            sortFile(fileNames);
            fileNameStr = fileNames[fileCount - 1];
            toInsert = new File(filePath.getAbsolutePath() + File.separator
                    + fileNameStr);
        }
        int recordCount = queryCountInFile(toInsert.getAbsolutePath());
        int recorded = 0;
        try {
            FileWriter fileWriter = new FileWriter(toInsert, true);
            for (String data : dataList) {
                fileWriter.append(data + NEXT_LINE);
                recorded++;
                if (recorded + recordCount == PAGE_SIZE) {
                    toInsert = createFile(field);
                    fileWriter.flush();
                    fileWriter = new FileWriter(toInsert, true);
                    recorded = 0;
                    recordCount = 0;
                }
            }
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
    
    /**
     * 返回指定记录的条数
     * 
     * @param field
     * @return
     */
    public static int queryCountByField(String field) {
        int totalRecord = 0;
        File filePath = queryFilePathByFieldName(field, false);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        sortFile(fileNames);
        // 最新文件的文件名
        String lastFilePath = filePath.getAbsolutePath() + File.separator
                + fileNames[fileCount - 1];
        totalRecord += PAGE_SIZE * (fileCount - 1);
        totalRecord += queryCountInFile(lastFilePath);
        return totalRecord;
    }
    
    /**
     * 根据字段名查询结果列表
     * @param field
     * @param limit
     * @param offset
     * @return
     */
    public static List<String> queryList(String field, int limit, int offset) {
        List<String> contentList = new ArrayList<String>(PAGE_SIZE);
        File filePath = queryFilePathByFieldName(field, false);
        // 文件偏移量
        int fileIndex = offset / PAGE_SIZE;
        // 记录偏移量
        int recordOffset = offset % PAGE_SIZE;
        
        String toReadFileStr = "";
        // 执行查询
        toReadFileStr = field + CONNECT_CHAR + fileIndex + FILE_EXT;
        queryListInFile(filePath.getAbsolutePath() + File.separator
                + toReadFileStr, limit, recordOffset, contentList);
        return contentList;
    }

    /**
     * 根据字段名查询数据所在路径
     * 
     * @param create
     * @return
     */
    private static File queryFilePathByFieldName(String field, boolean create) {
        String filePathStr = FILE_ROOT + field + File.separator;
        File filePath = new File(filePathStr);
        if (!filePath.exists() || !filePath.isDirectory()) {
            if (!create) {
                throw new IllegalArgumentException("记录不存在!");
            }
            if(!filePath.mkdirs()){
                throw new IllegalArgumentException("文件创建失败!");
            };
        }
        return filePath;
    }

    /**
     * 查询当前文件中有几条记录
     * 
     * @param fileName
     * @return
     */
    private static int queryCountInFile(String fileStr) {
        int count = 0;
        try {
            RandomAccessFile file = new RandomAccessFile(fileStr, "r");
            while (file.readLine() != null) {
                count++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 查询指定文件中的指定记录
     * 
     * @param fileStr 文件全路径
     * @param limit 查询条数
     * @param offset 查询偏移量
     * @param contentList 查询后结果存入
     * @return 查询结果
     */
    private static int queryListInFile(String fileStr, int limit, int offset,
            List<String> contentList) {
        RandomAccessFile file = null;
        try {
            file = new RandomAccessFile(fileStr, "r");
        } catch (FileNotFoundException e) {
            System.err.println("没有记录了!");
            return -1;
        }
        if(offset>0){
            skipLine(file, offset);
        }
        int added = 0;
        while (limit > 0) {
            String content = "";
            try {
                content = file.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (content == null) {
                System.err.println("超过记录总数,还差" + limit);
                break;
            }
            contentList.add(content);
            added++;
            limit--;
            if((added + offset) == PAGE_SIZE){
                String fileIdexStr = fileStr.substring(fileStr.lastIndexOf(CONNECT_CHAR) + 1, fileStr.lastIndexOf(FILE_EXT));
                int newFileIdex = Integer.parseInt(fileIdexStr) + 1;
                String newFileStr = fileStr.replace(fileIdexStr + FILE_EXT, newFileIdex + FILE_EXT);
                return queryListInFile(newFileStr, limit, 0, contentList);
            }
        }
        return 1;

    }

    /**
     * 跳过指定文件的指定行数
     * @param file
     * @param lineCount
     * @return
     */
    private static boolean skipLine(RandomAccessFile file, int lineCount) {
        boolean success = true;
        for (int i = 0; i < lineCount; i++) {
            try {
                file.readLine();
            } catch (IOException e) {
                e.printStackTrace();
                success = false;
            }
        }
        return success;
    }

    /**
     * 创建文件
     * @param filePathStr
     * @param fileNameStr
     * @return
     */
    private static File createFile(String fieldName) {
        File filePath = queryFilePathByFieldName(fieldName, false);
        String[] fileNames = filePath.list();
        int fileCount = fileNames.length;
        File toCreate = new File(filePath.getAbsolutePath() + File.separator
                + fieldName + CONNECT_CHAR + fileCount + FILE_EXT);
        try {
            toCreate.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return toCreate;
    }
    
    /**
     * 排序文件名
     * @param fileNames
     */
    private static void sortFile(final String[] fileNames){
        Arrays.sort(fileNames, new Comparator<String>(){
            @Override
            public int compare(final String s1, final String s2) {
                if(s1.length() != s2.length()){
                    if(s1.length()>s2.length()){
                        return 1;
                    }
                    return -1;
                }
                return s1.compareTo(s2);
            }
            
        });
    }
}
原文地址:https://www.cnblogs.com/xzs603/p/2949127.html