我有一个400+ GB的文件,例如:
ID Data ...4000+columns
001 dsa
002 Data
… …
17201297 asdfghjkl
我希望按照ID对文件进行分块,以便更快地检索数据,例如:
mylocation/0/0/1/data.json
mylocation/0/0/2/data.json
.....
mylocation/1/7/2/0/1/2/9/7/data.json
我的代码工作正常,但是无论我使用哪种循环结束写程序,它都至少需要159,206 milisoconds才能完成文件创建的0.001%。
在那种情况下,可以选择多线程来减少时间复杂度(例如一次写入100或1k文件)吗?
我当前的代码是:
int percent = 0;
File file = new File(fileLocation + fileName);
FileReader fileReader = new FileReader(file); // to read input file
BufferedReader bufReader = new BufferedReader(fileReader);
BufferedWriter fw = null;
LinkedHashMap<String, BufferedWriter> fileMap = new LinkedHashMap<>();
int dataCounter = 0;
while ((theline = bufReader.readLine()) != null) {
String generatedFilename = generatedFile + chrNo + "//" + directory + "gnomeV3.json";
Path generatedJsonFilePath = Paths.get(generatedFilename);
if (!Files.exists(generatedJsonFilePath)) {// create directory
Files.createDirectories(generatedJsonFilePath.getParent());
files.createFile(generatedJsonFilePath);
}
String jsonData = DBFileMaker(chrNo, theline, pos);
if (fileMap.containsKey(generatedFilename)) {
fw = fileMap.get(generatedFilename);
fw.write(jsonData);
} else {
fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(generatedFilename)));
fw.write(jsonData);
fileMap.put(generatedFilename, fw);
}
if (dataCounter == 172 * percent) {// As I know my number of rows
long millisec = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println("Upto: " + pos + " as " + (Double) (0.001 * percent)
+ "% completion successful." + " took: " + millisec + " miliseconds");
percent++;
}
dataCounter++;
}
for (BufferedWriter generatedFiles : fileMap.values()) {
generatedFiles.close();
}
最佳答案
那真的取决于您的存储空间。磁盘确实很喜欢顺序写入,因此多线程可能会对其性能产生不良影响。但是,SSD可能会受益于多线程写入。
您应该做的是将代码分成2个线程,其中一个线程创建要写入磁盘的数据缓冲区,而第二个线程仅写入数据。这样,您的磁盘将始终保持忙碌状态,而不必等待生成更多数据。
或者具有一个线程来生成要写入的缓冲区,但是使用java nio以便异步写入数据,同时继续生成下一个缓冲区。