读取和存储大型 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();