gpt4 book ai didi

java - 使用java更新具有大量数据的csv中的特定列

转载 作者:行者123 更新时间:2023-11-29 04:12:49 25 4
gpt4 key购买 nike

我有一个包含 80 万条记录的 csv 文件“主列表”,每条记录有 13 个值。cell[0] 和 cell[1] 的组合给出了唯一的记录,我需要更新 cell[12] 的值,说每条记录的状态。

我有另一个 csv 文件,上面写着“更新的子集列表”。这是文件“主列表”的子集。对于我的第二个 csv 中数量较少的所有记录,比如 10000,我需要更新单元格 [11] 也就是每个匹配记录的状态列值。

我尝试了直接 BufferedReader、来自 commons-csv 的 CsvParser 和来自 univocity.parsers 的 CsvParser。但是读取整个文件并创建 800K 的列表会导致内存不足异常。

相同的代码将部署在不同的服务器上,所以我希望有一个高效的代码来读取巨大的 csv 文件并更新相同的文件。

部分读取大文件并写入同一文件可能会损坏数据。

有关如何执行此操作的任何建议。 ??

文件 inputF = new File(inputFilePath);

if (inputF.exists()) {
InputStream inputFS = new FileInputStream(inputF);
BufferedReader br = new BufferedReader(new InputStreamReader(inputFS));
// skip the header of the file
String line = br.readLine();
mandatesList = new ArrayList<DdMandates>();

while ((line = br.readLine()) != null) {
mandatesList.add(mapToItem(line));
}

br.close();

内存问题通过分块解决。读取单行和写入单行可能会花费更多时间。我没有尝试过,因为我的问题已通过一次使用 10 万条记录的批处理并在写入 10 万条记录后清除列表来解决

现在的问题是更新状态循环过多....

我有两个 csv。主表(主列表)有 800 K 条记录然后我有一个子集 csv 也说它有 10 k 条记录。这个 csv 子集是从其他一些系统更新的,它的更新状态是“OK”和“NOT OK”。我需要在主表中更新此状态。我怎样才能以最好的方式做到这一点。 ???我使用的最愚蠢的方法是:-

 // Master list have batches but it contains 800 k records and 12 columns
List<DdMandates> mandatesList = new ArrayList<DdMandates>();
// Subset list have updated status
List<DdMandates> updatedMandatesList = new ArrayList<DdMandates>();
// Read Subset csv file and map DdMandates item and then add to updated mandate list


File inputF = new File(Property.inputFilePath);
if(inputF.exists()) {
InputStream inputFS = new FileInputStream(inputF);
BufferedReader br = new BufferedReader(new InputStreamReader(inputFS, "UTF-8"));

checkFilterAndmapToItem(br);

br.close();

In Method checkFilterAndmapToItem(BufferedReader br)

private static void checkFilterAndmapToItem(BufferedReader br) {
FileWriter fileWriter = null;
try {
// skip the header of the csv
String line = br.readLine();
int batchSize = 0, currentBatchNo=0;
fileWriter = new FileWriter(Property.outputFilePath);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
if( !Property.batchSize.isEmpty()) {
batchSize = Integer.parseInt(Property.batchSize.trim());
}
while ((line = br.readLine()) != null) {

DdMandates item = new DdMandates();
String[] p = line.concat(" ").split(SEPERATOR);
Parse each p[x] and map to item of type DdMandates\
Iterating here on updated mandate list to check if this item is present in updated mandate list
then get that item and update that status to item . so here is a for loop for say 10K elements
mandatesList.add(item);

if (batchSize != 0 && mandatesList.size() == batchSize) {
currentBatchNo++;
logger.info("Batch no. : "+currentBatchNo+" is executing...");
processOutputFile(fileWriter);
mandatesList.clear();
}
}
processing output file here for the last batch ...
}

它将有 while 循环(800 K 迭代){ 内部循环 10K 迭代每个元素)

所以至少 800K * 10K 循环

请帮助获得最佳方法并减少迭代。

提前致谢

最佳答案

假设您正在以 50K 的批处理读取“主数据文件”:

  • 将此数据存储在 java 中 HashMap使用 cell[0] 和 cell[1] 作为键,其余列作为值。

  • 大多数情况下,get 和 put 的复杂度为 O(1)。 see here

  • 因此,在该特定批处理中搜索 10K 条记录的复杂度将为 O(10K)。

    HashMap<String, DdMandates> hmap = new HashMap<String, DdMandates>();
  • 使用 key=DdMandates.get(0)+DdMandates.get(1)

注意:如果 50K 条记录超出了 HashMap 的内存限制,则创建较小的批处理。

  • 要进一步提高性能,您可以通过创建小批量并在不同线程上处理它们来使用多线程。

关于java - 使用java更新具有大量数据的csv中的特定列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54034540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com