读取和存储大型 ASCII 文件的内容
Read and store contents of large ASCII file
我得到了一个 538MB 的 ASCII 文件,有 16807 行,每行有 16807 个 0 和 1,由 space 分隔。我想获取所有这些值并将它们存储在一个列表列表中,就像将每一行存储在一个新列表中一样。
在之前的项目中,我为一个文本文件编写了以下代码,但对于 ASCII 文件,它抛出了一个 Java 堆 space 错误。
ArrayList<ArrayList<String>> listOflists = new ArrayList<ArrayList<String>>();
FileInputStream fstream = new FileInputStream("C:\Users...\file.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (true)
{
String line = br.readLine();
if (line == null) {
break;
}
Scanner tokenize = new Scanner(line);
ArrayList<String> tokens = new ArrayList<String>();
while (tokenize.hasNext())
{
tokens.add(tokenize.next());
}
listOflists.add(tokens);
}
br.close();
现在我编写了这段代码,但再次抛出 Java 堆 space 错误。
String inputFile = "C:\Users...\file.txt";
LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>();
File file = new File( inputFile );
Reader reader = new FileReader(file);
char val = 0;
int c;
int iLine = 0;
while( (c = reader.read()) != -1) {
val = (char)c;
charList.add(new LinkedList<Character>());
if((c == 48) || (c == 49)){ //ascii code for 0 is 48 and for 1 is 49
charList.get(iLine).add(val);
}
if( c == 92 ){ //ascii code for "/" is 92 as to know when it changes line
iLine++;
}
}
reader.close();
有什么想法吗?
您有一个空列表
LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>();
并且您正在尝试获取第一个元素
charList.get(iLine)
来自空列表,因此抛出 IndexOutOfBoundsException。
您正在为 while 循环的每次迭代添加一个新的 LinkedList
,即使该行没有更改也是如此。
我不知道我以前的代码到底哪里出错了,但这里有一个解决方案,我读取文件并将 1 的位置存储在列表中(首先是列,然后是我找到它的行) .
为了提供更多帮助,我还更改了项目的 VM 选项并添加 -Xmx1g 以增加堆大小。如果没有这个,我会得到一个 OutOfMemory 错误(运行 3G RAM 系统中的代码)
String inputFile = "C:\Users\...\file.txt";
FileInputStream in = new FileInputStream(inputFile);
FileChannel ch = in.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
ArrayList<Integer> list = new ArrayList<Integer>();
int column=-1;
int row=0;
int rd;
while ((rd = ch.read( buf )) != -1){
buf.flip();
while (buf.hasRemaining()){
byte byteVal = buf.get();
if((byteVal == 48) || (byteVal == 49)){ //ascii code for 0 is 48 and for 1 is 49
column++;
}
if (byteVal == 92){ //ascii code for "/" is 92 as to know when it changes line
row++;
column=0;
}
if(byteVal == 49){
list.add(column);
list.add(row);
}
}
buf.clear();
}
ch.close();
我得到了一个 538MB 的 ASCII 文件,有 16807 行,每行有 16807 个 0 和 1,由 space 分隔。我想获取所有这些值并将它们存储在一个列表列表中,就像将每一行存储在一个新列表中一样。
在之前的项目中,我为一个文本文件编写了以下代码,但对于 ASCII 文件,它抛出了一个 Java 堆 space 错误。
ArrayList<ArrayList<String>> listOflists = new ArrayList<ArrayList<String>>();
FileInputStream fstream = new FileInputStream("C:\Users...\file.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (true)
{
String line = br.readLine();
if (line == null) {
break;
}
Scanner tokenize = new Scanner(line);
ArrayList<String> tokens = new ArrayList<String>();
while (tokenize.hasNext())
{
tokens.add(tokenize.next());
}
listOflists.add(tokens);
}
br.close();
现在我编写了这段代码,但再次抛出 Java 堆 space 错误。
String inputFile = "C:\Users...\file.txt";
LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>();
File file = new File( inputFile );
Reader reader = new FileReader(file);
char val = 0;
int c;
int iLine = 0;
while( (c = reader.read()) != -1) {
val = (char)c;
charList.add(new LinkedList<Character>());
if((c == 48) || (c == 49)){ //ascii code for 0 is 48 and for 1 is 49
charList.get(iLine).add(val);
}
if( c == 92 ){ //ascii code for "/" is 92 as to know when it changes line
iLine++;
}
}
reader.close();
有什么想法吗?
您有一个空列表
LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>();
并且您正在尝试获取第一个元素
charList.get(iLine)
来自空列表,因此抛出 IndexOutOfBoundsException。
您正在为 while 循环的每次迭代添加一个新的 LinkedList
,即使该行没有更改也是如此。
我不知道我以前的代码到底哪里出错了,但这里有一个解决方案,我读取文件并将 1 的位置存储在列表中(首先是列,然后是我找到它的行) . 为了提供更多帮助,我还更改了项目的 VM 选项并添加 -Xmx1g 以增加堆大小。如果没有这个,我会得到一个 OutOfMemory 错误(运行 3G RAM 系统中的代码)
String inputFile = "C:\Users\...\file.txt";
FileInputStream in = new FileInputStream(inputFile);
FileChannel ch = in.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
ArrayList<Integer> list = new ArrayList<Integer>();
int column=-1;
int row=0;
int rd;
while ((rd = ch.read( buf )) != -1){
buf.flip();
while (buf.hasRemaining()){
byte byteVal = buf.get();
if((byteVal == 48) || (byteVal == 49)){ //ascii code for 0 is 48 and for 1 is 49
column++;
}
if (byteVal == 92){ //ascii code for "/" is 92 as to know when it changes line
row++;
column=0;
}
if(byteVal == 49){
list.add(column);
list.add(row);
}
}
buf.clear();
}
ch.close();