日期:2014-05-20 浏览次数:20715 次
package to.shin.sai; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.RandomAccessFile; public class Test4ReadLargeFile { private final long LAST_LINE_COUNT = 10; private final long MAX_LINE_COUNT = 400; private final int MAX_THREAD_COUNT = 5; private String[][] resArr = null; private boolean[] finished = null; private String fileEncode = ""; Object lock = new Object(); /** * @param args */ public static void main(String[] args) { String filePath = "c:\\largeFile.txt"; Test4ReadLargeFile trlf = new Test4ReadLargeFile(); trlf.read(filePath, "SJIS"); } public void read(String filePath, String charset) { long beginTime = System.currentTimeMillis(); System.out.println("开始时间:" + beginTime); this.fileEncode = charset; RandomAccessFile raf = null; try { raf = new RandomAccessFile(filePath, "r"); long fileSize = raf.length(); long beginPos = (MAX_LINE_COUNT - LAST_LINE_COUNT) * fileSize / MAX_LINE_COUNT; long length = fileSize - beginPos; long perLength = length / MAX_THREAD_COUNT; resArr = new String[MAX_THREAD_COUNT][]; finished = new boolean[MAX_THREAD_COUNT]; for (int i = 0; i < MAX_THREAD_COUNT; i++) { new ReadFileThread(beginPos + i * perLength, Math.min(beginPos + (i + 1) * perLength, fileSize - 1), filePath, i).start(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (null != raf) try { raf.close(); } catch (IOException ioe) { } } //等待结束 synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { } } long endTime = System.currentTimeMillis(); System.out.println("结束时间:" + endTime); System.out.println("耗时:" + (endTime - beginTime) + "ms"); } class ReadFileThread extends Thread { // the begin position private long beginPos = 0L; // the end position private long endPos = 0L; // the current position private long curPos = 0L; // the file private RandomAccessFile raf = null; private int resIndex = 0; public ReadFileThread(long beginPos, long endPos, String filePath, int resIndex) throws Exception { super("ReadFileThread: " + resIndex); if (endPos - beginPos > Integer.MAX_VALUE) throw new Exception("It's too large size to read for this job"); this.beginPos = beginPos; this.endPos = endPos; this.resIndex = resIndex; raf = new RandomAccessFile(filePath, "r"); raf.seek(beginPos); } private boolean checkRun() { try { // 起点和终点在同一行的话,不需要读 raf.seek(beginPos); raf.readLine(); long beginLine = raf.getFilePointer(); raf.seek(endPos); raf.readLine(); long endLine = raf.getFilePointer(); raf.seek(beginPos); if (beginLine == endLine) return false; } catch (Exception e) { e.printStackTrace(); } return true; } @Override public void run() { if (!checkRun()) return; try { // skip the first line raf.readLine(); curPos = raf.getFilePointer(); byte[] content = new byte[(int) (endPos - curPos + 1)]; int offset = 0; while (curPos + offset <= endPos) { offset += raf.read(content, offset, (int) (content.length - offset)); } byte[] res = content; // 读取最后一行 byte[] lastBytes = new byte[1024]; raf.read(lastBytes); int returnKeyIndex = 0; // 假设最后一行最大不超过1K,如果考虑全,还要写完整(我懒) for (int i = 0; i < lastBytes.length; i++) { if (lastBytes[i] == 10 || lastBytes[i] == 13) { returnKeyIndex = i; break; } } res = new byte[offset + returnKeyIndex]; System.arraycopy(content, 0, res, 0, offset); System.arraycopy(lastBytes, 0, res, offset, returnKeyIndex); String resStr = new String(res, fileEncode); resStr = resStr.replaceAll("\r", ""); resArr[resIndex] = resStr.split("\n"); noticeFinished(resIndex); } catch (Exception e) { e.printStackTrace(); } finally { if (null != raf) try { raf.close(); } catch (IOException ioe) { } } super.run(); } } private void noticeFinished(int index) { finished[index] = true; System.out.println("Thread " + index + " is over."); for (boolean f : finished) if (!f) return; synchronized (lock) { lock.notify(); } finish(); System.out.println("all data is readed"); } private void finish() { PrintWriter pw = null; try { pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("c:\\result.txt"), fileEncode)); for (int i = 0; i < resArr.length; i++) if (null != resArr[i]) for (int j = 0; j < resArr[i].length; j++) { pw.println(resArr[i][j]); } } catch (Exception e) { e.printStackTrace(); } finally { if (null != pw) try { pw.close(); } catch (Exception ioe) { } } } }