0

我有一个非常大ByteBuffer的,大小约为几 MB。当我ByteBuffer进入

FileChannel fc = new FileInputStream(new File(decodedUri)).getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
CharBuffer cb;
if (encoding == null)
    encoding = "UTF-8";
cb = Charset.forName(encoding).decode(bb);

OutOfMemoryError每隔一次就可以跟踪堆栈跟踪Charset.decode。正是这一行触发了错误。

cb = Charset.forName(encoding).decode(bb);

我该如何解决?

因为第一次启动应用程序时 OutOfMemoryError 没有被触发,只有我第二次尝试启动它时,才会出现此错误。我想知道我需要做的缓冲区是否有某种刷新?或者类似的东西?

4

1 回答 1

2

如果你想分块读取那个巨大的文件,你可以这样做AsyncTask

static class StreamTask extends AsyncTask<String, Void, Integer> {
    private static final int BUFFER_LENGTH = 1024 * 8; // Adjust to taste

    // Param #0 = file name
    // Param #1 = charset name
    @Override
    protected Integer doInBackground(String... params) {

        if (params.length != 2) {
            throw new IllegalArgumentException();
        }

        int chars = 0;
        CharsetDecoder cd = Charset.forName(params[1]).newDecoder();
        try {
            FileInputStream fin = new FileInputStream(params[0]);
            try {
                FileChannel fc = fin.getChannel();
                ByteBuffer bb = ByteBuffer.allocateDirect(BUFFER_LENGTH);
                CharBuffer cb = CharBuffer.allocate(BUFFER_LENGTH);

                while (fc.read(bb) != -1) {
                    // Flip the buffer, decode the contents
                    bb.flip();
                    cd.decode(bb, cb, false); // You should probably look at CoderResult also.
                    // Flip & extract the decoded characters.
                    cb.flip();
                    chars += cb.remaining();
                    onCharacters(cb.array(), cb.position(), cb.remaining());
                    cb.clear();
                    // Prepare the buffer for reuse.
                    bb.compact();
                }

                // fc.read(..) returned -1 -> EOF, but bb may still contain
                // stuff to decode.
                bb.flip();
                cd.decode(bb, cb, true);
                cd.flush(cb);
                cb.flip();
                if (cb.remaining() > 0) {
                    chars += cb.remaining();
                    onCharacters(cb.array(), cb.position(), cb.remaining());
                }
            } finally {
                fin.close();
            }

        } catch (IOException e) {
            chars = -1;
        }
        return chars;
    }


    protected void onCharacters(char[] ch, int offset, int length) {
        // Do something with the characters (still running in the AsyncTask thread)
    }
}
于 2012-11-26T16:18:54.487 回答