为什么我的文件有种族条件,即使我使用了标准popenoption.sync?

问题描述 投票:0回答:0

我有一个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

,但我也得到了相同的结果,将其作为普通文件运行。 IntStream .range(0, 10) .mapToObj(String::valueOf) .map(Path::of) .map ( path -> { try { return Files.lines(path); } catch (final Exception e) { throw new RuntimeException(e); } } ) .map ( stream -> stream .filter(s -> !s.equals("")) .mapToLong(Long::parseLong) .summaryStatistics() ) .forEach(System.out::println) ;

这确实为10个文件中的每个文件打印出来。
我的输出是我的输出。
LongSummaryStatistics


numpRefix
count

sum

Min
水 max01000.000000 0671067271105847657060398169543.4237001996215711700017211110807936118810008566710084252998905.3510402999558127899730311110948726950006539566180065426461049.00915536998819303450594111107611580564487107366570142255286303.731720498025034504234251111084212910966235669867530116201510521.613650599024595049421261111068321400465239191704440192611608478.000000 78035037312478.957500899317398741891291111079529302548089938679700263730435940.3506209996168394101800现在,立即突然出现给我的是每列的最大值。太高了。有些人报告了四千千万中的数字。此外,每个人的分钟为0。他们应该一样,对吗? 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);
java parallel-processing synchronization java-stream collectors
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.