gpt4 book ai didi

java - 读取巨大的csv文件,将其存储为Person对象,写入多个更清洁或更小的CSV文件时出现内存问题

转载 作者:行者123 更新时间:2023-11-29 08:53:14 27 4
gpt4 key购买 nike

我有两个带有逗号分隔值的文本文件。一个是150MB,另一个是370MB,因此这些家伙拥有300万以上的数据行。

一个文档包含有关的信息,比如说汽水偏好设置,而另一个文档则包含有关的信息,比如说染发剂。

示例性软饮料数据文件,尽管在真实文件中,UniqueNames顺序不正确,日期也不是:

"UniqueName","softDrinkBrand","year"
"001","diet pepsi","2004"
"001","diet coke","2006"
"001","diet pepsi","2004"
"002","diet pepsi","2005"
"003","coca cola","2004"


本质上,有太多数据行无法使用excel,因此我想使用Person类创建Person对象来保存有关每个人的数据。

每个Person对象拥有20个数组列表,2004-2013年的十年中,每个数组列表都有两个,例如,

...
private ArrayList<String> sodas2013= new ArrayList<String>();
private ArrayList<String> hairColors2013= new ArrayList<String>();
private ArrayList<String> sodas2014= new ArrayList<String>();
private ArrayList<String> hairColors2014= new ArrayList<String>();
...


我编写了一个程序,使用BufferedReader一次读取一个数据文件的行。
对于每一行,我都要清理数据(用逗号分隔,删除引号...),然后,如果该特定的uniqueID不在哈希表中,则添加它,并创建一个新的Person对象。从我的Person类中,然后将所需的数据存储到如上所述的Person类的ArrayList中。如果已经存在唯一的ID,我只需调用Person方法即可查看该特定年份的数组列表中是否已经存在苏打水或发色(如csv文件中所述)。

目标是最终输出20个不同的csv文件,其中一个将人与每年喝的苏打水联系在一起,一个与该年的头发颜色联系在一起。他们看起来像这样...

使用上面示例输入文件的2004文件:

UID    pepsi    coca cola    diet pepsi    diet coke    etc
001 false false true false etc
002 false false false false etc
003 false true false false etc


现在,当我每个测试文件只有100行时,它的运行效果非常好。我将所有数据保存在我的Person对象中,然后使用方法按存储在Person对象中的年份将Hashtable uniqueNames与uniqueSoftDrinkNames匹配,以写入带有personID行的文件,然后对任何uniqueID尝试过的所有可能的汽水写入true / false。任何一年。数据看起来像上面的信息。

因此,我知道代码可以工作并且可以实现我想要的功能。现在的问题是...

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Unknown Source)
at java.lang.String.<init>(Unknown Source)
at java.lang.StringBuffer.toString(Unknown Source)
at java.util.regex.Matcher.appendReplacement(Unknown Source)
at java.util.regex.Matcher.replaceAll(Unknown Source)
at java.lang.String.replaceAll(Unknown Source)
at CleanDataFiles.main(CleanDataFiles.java:43)


第43行是:

temp = temp.replaceAll("\"", "");


...这只是在用逗号分隔一行后,去除给定子字符串中引号的简单点。

运行此程序的计算机大约需要十分钟才能达到此错误,并且我两次运行该程序时,都给了我相同的错误和同一行。

我正在逐行读取CSV文档,因此在读取文件时,我不会将大量数据存储在巨大的字符串或任何其他内容中。我要存储大量数据的唯一位置是在主类的哈希表中,其中存储了personID和personObjects,还有两个哈希表,在其中存储了所有可能的头发颜色和所有可能的苏打水,以及所有这些人对象中的每个并按年份列出了全部苏打水和发色信息的二十个数组列表。

我的假设是,内存问题在于将这些成千上万的唯一个人对象与所有与之关联的数据一起存储。就是说,我在程序的同一位置出现了错误,我只读取csv文件并清理单个条目...

无论如何,我的问题(你们都在等待!)

有更好的方法可以做到这一点吗?而不是保存所有这些数据的成千上万或成千上万的Person对象……我应该创建成千上万的Person文本文件,并在每次读取CSV文件的新行并查询是否是否打开并关闭它们时查询该信息是重复信息还是新信息,如果是新信息,请将其添加到“个人”文件中?一切都说完之后,打开每个人员文件以读取信息,进行解释,然后一次将其写入我不断增长的输出文件中,关闭该人员文件,然后为下一行打开下一个文件,等等。?

或者,希望如此,您认为这整个混乱中的其他地方是否有一个更傻,更容易解决的问题,以便在清理和整理数据文件以进行进一步分析时不会耗尽内存?

我感谢任何帮助或建议!谢谢。

最佳答案

这里有一些想法。首先,可能是您的计算机上有足够的可用内存,但是没有为JVM分配足够的内存。尝试这样的事情:

java -Xms2048M -Xmx4096M YourProgram

当然,这些值将取决于计算机的内存量。

另外,为什么在每个Person对象中使用String的ArrayList?如果您可以提前确定可能的苏打水或其他任何东西,则可以使用一个int数组,这样可以节省一些内存。

另一种选择是分段进行,先做苏打水,完成后做染发等。

关于java - 读取巨大的csv文件,将其存储为Person对象,写入多个更清洁或更小的CSV文件时出现内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21637293/

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