CSV Java 文件读取和保存(在不同的ArrayList中)
CSV Java file reading and saving (in different ArrayList)
好的伙计们,这是我的代码。
我遇到了一个问题,因为 "records.csv" 是一个包含 2000 万行的文件,每行由 4 个字段组成,用 ',' 分隔。
正如您从代码中了解到的那样,我想要 4 个数组列表,每个数组列表都包含不同字段的所有值。
一段时间后该方法停止工作(我认为是因为要 'add' 列表中的一个元素,java 有一个指针必须先遍历所有数组列表)。
我需要解决,但我不知道如何解决。
建议?
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class RecordReader {
static ArrayList<String> id = new ArrayList <String> ();
static ArrayList<String> field1 = new ArrayList <String> ();
static ArrayList<String> field2 = new ArrayList <String> ();
static ArrayList<String> field3 = new ArrayList <String> ();
public static void Reader () {
try {
FileReader filein = new FileReader("Y:/datasets/records.csv");
String token="";
String flag = "id";
int index=0, next;
do {
next = filein.read();
if (next != -1) {
if (next !=',' && next !='\n')
token = token + next;
else if (next == ','){
if (flag.compareTo("id")==0) {id.add (index, token); flag = "field1";}
else if (flag.compareTo("field1")==0) {field1.add (index, token); token=""; flag = "field2";}
else if (flag.compareTo("field2")==0) {field2.add (index, token); token=""; flag = "field3";}
}
else if (next == '\n') {
if (flag.compareTo("field3")==0) {field3.add (index, token); token=""; flag = "id"; index++;}
}
char nextc = (char) next;
System.out.print(nextc);
}
} while (next!=-1);
filein.close();
}
catch (IOException e) { System.out.println ("ERRORE, birichino!"); }
}
}
我必须一次完成,文件有 711000 字节。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.nio.CharBuffer.wrap(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at RecordReader.Reader(RecordReader.java:42)
at prova.main(prova.java:26)
我有几个建议给你。
首先,您不需要有 4 个单独的 ArrayLists
,一个就可以了。而不是使用 filein.read()
,我会用 BufferedReader
包装你的 FileReader
并使用它逐行读取文件并将每一行添加到单个 ArrayList
.
BufferedReader br = new BufferedReader(filein);
ArrayList<String> content = new ArrayList<String>();
String line = br.readLine();
while(line != null){
//add lines to ArrayList
content.add(line);
line = br.readLine();
}
这会将整个文件的内容读取到内存中,而不会产生 3 个额外的额外开销 ArrayLists
。
其次,由于您的字段由 ,
分隔并且(我假设)始终具有相同数量的字段,您可以使用 split() 方法将每一行分隔成一个字符串数组。
String[] record = content.get(index).split(",");
//record[0] = id
//record[1] = field1
//record[2] = field2
//record[3] = field3
将上面的代码放入一个循环中,您就可以遍历文件的所有内容。因为您知道信息是如何排序的,所以检索您想要的信息很容易。
但是,我会警告你,如果文件足够大(有数 GB 的数据),最终这种方法也会失败。
你能试试运行 应用程序的-Xmx 选项如下所示
java-Xmx6g[java类文件]
我能够解决类似的问题。
好的伙计们,这是我的代码。 我遇到了一个问题,因为 "records.csv" 是一个包含 2000 万行的文件,每行由 4 个字段组成,用 ',' 分隔。
正如您从代码中了解到的那样,我想要 4 个数组列表,每个数组列表都包含不同字段的所有值。 一段时间后该方法停止工作(我认为是因为要 'add' 列表中的一个元素,java 有一个指针必须先遍历所有数组列表)。
我需要解决,但我不知道如何解决。
建议?
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class RecordReader {
static ArrayList<String> id = new ArrayList <String> ();
static ArrayList<String> field1 = new ArrayList <String> ();
static ArrayList<String> field2 = new ArrayList <String> ();
static ArrayList<String> field3 = new ArrayList <String> ();
public static void Reader () {
try {
FileReader filein = new FileReader("Y:/datasets/records.csv");
String token="";
String flag = "id";
int index=0, next;
do {
next = filein.read();
if (next != -1) {
if (next !=',' && next !='\n')
token = token + next;
else if (next == ','){
if (flag.compareTo("id")==0) {id.add (index, token); flag = "field1";}
else if (flag.compareTo("field1")==0) {field1.add (index, token); token=""; flag = "field2";}
else if (flag.compareTo("field2")==0) {field2.add (index, token); token=""; flag = "field3";}
}
else if (next == '\n') {
if (flag.compareTo("field3")==0) {field3.add (index, token); token=""; flag = "id"; index++;}
}
char nextc = (char) next;
System.out.print(nextc);
}
} while (next!=-1);
filein.close();
}
catch (IOException e) { System.out.println ("ERRORE, birichino!"); }
}
}
我必须一次完成,文件有 711000 字节。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.nio.CharBuffer.wrap(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at RecordReader.Reader(RecordReader.java:42)
at prova.main(prova.java:26)
我有几个建议给你。
首先,您不需要有 4 个单独的 ArrayLists
,一个就可以了。而不是使用 filein.read()
,我会用 BufferedReader
包装你的 FileReader
并使用它逐行读取文件并将每一行添加到单个 ArrayList
.
BufferedReader br = new BufferedReader(filein);
ArrayList<String> content = new ArrayList<String>();
String line = br.readLine();
while(line != null){
//add lines to ArrayList
content.add(line);
line = br.readLine();
}
这会将整个文件的内容读取到内存中,而不会产生 3 个额外的额外开销 ArrayLists
。
其次,由于您的字段由 ,
分隔并且(我假设)始终具有相同数量的字段,您可以使用 split() 方法将每一行分隔成一个字符串数组。
String[] record = content.get(index).split(",");
//record[0] = id
//record[1] = field1
//record[2] = field2
//record[3] = field3
将上面的代码放入一个循环中,您就可以遍历文件的所有内容。因为您知道信息是如何排序的,所以检索您想要的信息很容易。
但是,我会警告你,如果文件足够大(有数 GB 的数据),最终这种方法也会失败。
你能试试运行 应用程序的-Xmx 选项如下所示
java-Xmx6g[java类文件]
我能够解决类似的问题。