提交 db613091 authored 作者: Thomas Mueller's avatar Thomas Mueller

Tool to view very large files (initial version).

上级 c4fffda5
/*
* Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.dev.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import org.h2.util.Tool;
/**
* A text file viewer that support very large files.
*/
public class FileViewer extends Tool {
/**
* Run the viewer.
*
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
new FileViewer().run(args);
}
private void showUsage() {
out.println("A text file viewer that support very large files.");
out.println("java "+getClass().getName() + "\n" +
" -file <file> The name of the file to view\n" +
" [-find <text>] Find a string and display the next lines\n" +
" [-head] Display the first lines\n" +
" [-tail] Display the last lines\n" +
" [-lines <x>] Display only x lines (default: 30)\n" +
" [-quiet] Do not print progress information)");
// out.println("See also http://h2database.com/javadoc/" + getClass().getName().replace('.', '/') + ".html");
}
public void run(String[] args) {
String file = null;
String find = null;
boolean head = false, tail = false;
int lines = 30;
boolean quiet = false;
for (int i = 0; args != null && i < args.length; i++) {
String arg = args[i];
if (arg.equals("-file")) {
file = args[++i];
} else if (arg.equals("-find")) {
find = args[++i];
} else if (arg.equals("-head")) {
head = true;
} else if (arg.equals("-tail")) {
tail = true;
} else if (arg.equals("-lines")) {
lines = Integer.decode(args[++i]).intValue();
} else if (arg.equals("-quiet")) {
quiet = true;
} else if (arg.equals("-help") || arg.equals("-?")) {
showUsage();
return;
} else {
out.println("Unsupported option: " + arg);
showUsage();
return;
}
}
if (file == null) {
showUsage();
return;
}
if (!head && !tail && find == null) {
head = true;
}
try {
process(file, find, head, tail, lines, quiet);
} catch (IOException e) {
e.printStackTrace();
}
}
private void process(String fileName, String find, boolean head, boolean tail, int lines, boolean quiet) throws IOException {
RandomAccessFile file = new RandomAccessFile(fileName, "r");
long length = file.length();
if (head) {
file.seek(0);
list(0, "Head", readLines(file, lines));
}
if (find != null) {
long pos = find(file, find.getBytes(), quiet);
if (pos >= 0) {
file.seek(pos);
list(pos, "Found " + find, readLines(file, lines));
}
}
if (tail) {
long pos = length - 100 * lines;
ArrayList list = null;
while (pos > 0) {
file.seek(pos);
list = readLines(file, Integer.MAX_VALUE);
if (list.size() > lines) {
break;
}
pos -= 100 * lines;
}
// remove the first (maybe partial) line
list.remove(0);
while (list.size() > lines) {
list.remove(0);
}
list(pos, "Tail", list);
}
}
private long find(RandomAccessFile file, byte[] find, boolean quiet) throws IOException {
long pos = file.getFilePointer();
long length = file.length();
int bufferSize = 4 * 1024;
byte[] data = new byte[bufferSize * 2];
long last = System.currentTimeMillis();
while (pos < length) {
System.arraycopy(data, bufferSize, data, 0, bufferSize);
if (pos + bufferSize > length) {
file.readFully(data, bufferSize, (int) (length - pos));
return find(data, find, (int) (bufferSize + length - pos - find.length));
}
if (!quiet) {
long now = System.currentTimeMillis();
if (now > last + 5000) {
System.out.println((100 * pos / length) + "%");
last = now;
}
}
file.readFully(data, bufferSize, bufferSize);
int f = find(data, find, bufferSize);
if (f >= 0) {
return f + pos - bufferSize;
}
pos += bufferSize;
}
return -1;
}
private int find(byte[] data, byte[] find, int max) {
outer:
for (int i = 0; i < max; i++) {
for (int j = 0; j < find.length; j++) {
if (data[i + j] != find[j]) {
continue outer;
}
}
return i;
}
return -1;
}
private void list(long pos, String header, ArrayList list) {
System.out.println("-----------------------------------------------");
System.out.println("[" + pos + "]: " + header);
System.out.println("-----------------------------------------------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-----------------------------------------------");
}
private ArrayList readLines(RandomAccessFile file, int maxLines) throws IOException {
ArrayList lines = new ArrayList();
ByteArrayOutputStream buff = new ByteArrayOutputStream(100);
boolean lastNewline = false;
while (maxLines > 0) {
int x = file.read();
if (x < 0) {
break;
}
if (x == '\r' || x == '\n') {
if (!lastNewline) {
maxLines--;
lastNewline = true;
byte[] data = buff.toByteArray();
String s = new String(data);
lines.add(s);
buff.reset();
}
continue;
}
if (lastNewline) {
lastNewline = false;
}
buff.write(x);
}
byte[] data = buff.toByteArray();
if (data.length > 0) {
String s = new String(data);
lines.add(s);
}
return lines;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论