我有一个CSV文件,该文件太大而无法适合RAM,仅适用于我的硬盘。我需要将此CSV文件分为一部分。
我正在使用
BufferedReader.lines()
来流式传输文件,现在我想使用Collector
写出零件。我知道这可能不是理想的,但实际上,手头的任务并不是真正的重点。
使我感到困惑的部分是StandardOpenOption.SYNC
的行为。这是我的代码。
import java.nio.file.*;
import java.util.function.*;
import java.util.stream.*;
import java.util.*;
import static java.nio.file.StandardOpenOption.*;
public class temp2
{
public static final Path parentFolder =
Path
.of(".")
.toAbsolutePath()
.normalize()
;
public static void main(final String[] args) throws Exception
{
System.out.println(parentFolder);
for (int i = 0; i < 10; i++)
{
Files.deleteIfExists(parentFolder.resolve(String.valueOf(i)));
}
final int LIMIT = 100_000;
final HashMap<String, List<String>> blahs =
IntStream
.range(0, 100_000_000)
.parallel()
.mapToObj(String::valueOf)
.collect
(
Collector
.of
(
HashMap::new,
(map, s) ->
{
final String key = String.valueOf(s.charAt(0));
final List<String> list = map.compute(key, (k, v) -> v == null ? new ArrayList<>() : v);
list.add(s);
if (list.size() > LIMIT)
{
writeThenClearList(key, list);
}
},
(HashMap<String, List<String>> oldMap, HashMap<String, List<String>> newMap) ->
{
System.out.println(oldMap.values().stream().flatMap(Collection::stream).count());
System.out.println(newMap.values().stream().flatMap(Collection::stream).count());
System.out.println("---");
oldMap.forEach(temp2::writeThenClearList);
newMap.forEach(temp2::writeThenClearList);
return new HashMap<>();
},
(map) ->
{
map.forEach(temp2::writeThenClearList);
return map;
}
)
)
;
blahs.entrySet().forEach(System.out::println);
}
private static void writeThenClearList(final String key, final List<String> list)
{
if (list.isEmpty())
{
return;
}
try {
Files
.write(
parentFolder.resolve(key),
list,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.APPEND,
StandardOpenOption.SYNC
);
} catch (final Exception e) {
throw new RuntimeException(e);
}
list.clear();
}
}
写作感觉很简单 - 它仅生成0到1亿之间的所有数字,然后根据起始数字将它们分组为文件。因此,0进入TE 0文件,1进入1个文件,10进入1个文件,20进入2个文件,300进入3个文件,等等。我还特别注意使用
StandardOpenOption.SYNC
,为了分析结果,我然后写了以下代码。我使用了
jshell
这确实为10个文件中的每个文件打印出来。
我的输出是我的输出。
LongSummaryStatistics
numpRefixcount
sum
Min
LongSummaryStatistics{count=1, sum=0, min=0, average=0.000000, max=0}
LongSummaryStatistics{count=11110722, sum=671067271105847657, min=0, average=60398169543.423700, max=1996215711700017}
LongSummaryStatistics{count=11110807, sum=936118810008566710, min=0, average=84252998905.351040, max=2999558127899730}
LongSummaryStatistics{count=11110948, sum=726950006539566180, min=0, average=65426461049.009155, max=3699881930345059}
LongSummaryStatistics{count=11110761, sum=1580564487107336657, min=0, average=142255286303.731720, max=4980250345042342}
LongSummaryStatistics{count=11110842, sum=1291096623566986753, min=0, average=116201510521.613650, max=5990245950494212}
LongSummaryStatistics{count=11110683, sum=2140046523919170444, min=0, average=192611608478.000000, max=6999483760545061}
LongSummaryStatistics{count=11110881, sum=1629411286034487818, min=0, average=146650052865.698760, max=7993937378575107}
LongSummaryStatistics{count=11110718, sum=3892896980864594155, min=0, average=350373124478.957500, max=8993173987418912}
LongSummaryStatistics{count=11110795, sum=2930254808993867970, min=0, average=263730435940.350620, max=9996168394101800}
调用1 | 11110722 | ||||
6999483760545061 | |||||
11110881 | 1629411286034487818 | 0 | 146650052865.698760 | 7993937378575107 | |
11110718 | 3892896980864594155 | ||||
,好的,我们有一个比赛状况。但是,我没有得到的是为什么 | 没有保护我的原因。那不是它的工作吗? | 如果不是它的工作,那么该选项到底对我有什么作用? | 您正在使用平行流 | StandardOpenOption.SYNC |
writeThenClearList(key, list); |