1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
public class FileRead {
private static final Logger LOGGER = LoggerFactory.getLogger(FileRead.class);
private static final Charset UTF8 = StandardCharsets.UTF_8;
// 回车符
private static final int LF = 10;
// 换行符
private static final int CR = 13;
public static void main(String[] args) {
String file = "C:\\ProgramData\\chocolatey\\logs\\chocolatey.log";
StopWatch stopWatch = StopWatch.create("1");
// run(() -> byteRead(file), stopWatch);
run(() -> bufferedRead(file), stopWatch);
run(() -> streamRead(file), stopWatch);
run(() -> scannerRead(file), stopWatch);
run(() -> readLine(file), stopWatch);
LOGGER.info(stopWatch.prettyPrint());
}
/**
* 按字节读取
*/
// public static void byteRead(String file) {
// try (InputStream is = new FileInputStream(new File(file))) {
// while (is.read() != -1) {
// // do something
// }
// } catch (Exception e) {
// LOGGER.error("错误", e);
// }
// }
/**
* BufferReader按行读取
*/
public static void bufferedRead(String file) {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
while (br.readLine() != null) {
// do something
}
} catch (IOException e) {
LOGGER.error("错误", e);
}
}
/**
* Stream按行读取
*/
public static void streamRead(String file) {
try (Stream<String> stream = Files.lines(Paths.get(file))) {
} catch (IOException e) {
LOGGER.error("错误", e);
}
}
/**
* Scanner按行读取
*/
public static void scannerRead(String file) {
try (Scanner scan = new Scanner(new File(file))) {
while (scan.hasNextLine()) {
scan.nextLine();
}
} catch (IOException e) {
LOGGER.error("错误", e);
}
}
/**
* NIO按行读取
*/
public static void readLine(String fileName) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "rw");
FileChannel channel = randomAccessFile.getChannel()) {
// 每次读取的buffer
ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
// 期望每行占用的buffer
ByteBuffer stringBuffer = ByteBuffer.allocate(20);
// 从文件中读数据到buffer中
while (channel.read(buffer) != -1) {
// 切换模式,写->读
buffer.flip();
while (buffer.hasRemaining()) {
byte b = buffer.get();
// 换行或回车
if (b == LF || b == CR) {
stringBuffer.flip();
// 解码已经读到的一行所对应的字节
UTF8.decode(stringBuffer).toString();
// System.out.println(line + "----------");
stringBuffer.clear();
} else {
// 空间不够扩容
if (!stringBuffer.hasRemaining()) {
stringBuffer = reAllocate(stringBuffer);
}
stringBuffer.put(b);
}
}
// 清空,position位置为0,limit=capacity
buffer.clear();
}
} catch (Exception e) {
LOGGER.error("错误", e);
}
}
private static ByteBuffer reAllocate(ByteBuffer stringBuffer) {
final int capacity = stringBuffer.capacity();
// 扩容至两倍
byte[] newBuffer = new byte[capacity * 2];
System.arraycopy(stringBuffer.array(), 0, newBuffer, 0, capacity);
// 生成新的ByteBuffer,并移动到position
return (ByteBuffer) ByteBuffer.wrap(newBuffer).position(capacity);
}
private static void run(Runnable r, StopWatch sw) {
sw.start();
r.run();
sw.stop();
}
}
|