Java 分段从文件中读取数据的一个例子

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

/**
* 分段从文件中读取数据
*
* @author chen_k
*
*/
@Component
public class GrabDataService {

/**
* 每次从文件中读取的行数,默认 5000 行
*/
public static final int LINE_COUNT = 5000;

/**
* 文件默认编码
*/
public static final String FILE_ENCODING = "UTF-8";

private static final Logger log = LoggerFactory.getLogger(GrabDataService.class);

/**
* 文件的唯一标识Map,用于记录从文件的哪一行开始读取
*/
private Map<String, Integer> counterMap = Collections.synchronizedMap(new HashMap<String, Integer>());

/**
* 每次从文件中读取固定行数的记录
* @param msgKey 文件的唯一标识
* @param filePath 文件路径
* @return List<Map<Integer, String>> 读取的文件内容
*/
public List<Map<Integer, String>> getFileData(String msgKey, String filePath) {
List<Map<Integer, String>> dataList = new ArrayList<>();

int line = 0;
if (counterMap.get(msgKey) == null) {
counterMap.put(msgKey, line);
} else {
line = counterMap.get(msgKey);
}

try {
File file = new File(filePath);
if (file.isFile() && file.exists()) { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(new FileInputStream(file), FILE_ENCODING);// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;

int index = 1;
while ((lineTxt = bufferedReader.readLine()) != null) {
// 每次取的时候从上次最后的行开始
if (index > line) {
Map<Integer, String> data = new HashMap<>();
data.put(index, lineTxt);
dataList.add(data);

// 每次只取文件的 5000 条
if ((index - line) == LINE_COUNT) {
line = index;
break;
}
}
index ++;
}
// 说明文件已经读完,插入一个读完的标记, file.renameTo(file) 用于判断当前文件是否被其他程序写入内容或占用
if (lineTxt == null && file.renameTo(file)) {
Map<Integer, String> data = new HashMap<>();
data.put(-1, "END OF FILE");
dataList.add(data);

line = index;
}

read.close();
bufferedReader.close();
} else {
log.error("找不到指定的文件:{}", new Object[]{filePath});
}
} catch (Exception e) {
log.error("读取文件内容出现异常", e);
} finally {
// 记录下一次从文件的哪一行开始读取
counterMap.put(msgKey, line);
log.info("msgKey={},filePath={},line={}", new Object[]{msgKey,filePath,line});
}

return dataList;
}

/**
* 重置从文件的开始读取行数
*
* @param msgKey 文件的唯一标识
* @param offset 开始读取行数
*/
public void relocateTo(String msgKey, int offset) {
counterMap.put(msgKey, offset);
}

public GrabDataService() {
}

}
Buy me a cup of coffee