Skip to content

Android MappedByteBuffer文件映射内存使用示例

频繁读写io会造成性能问题。有没有另外一种读写文件的方式呢?

使用RandomAccessFile来获取MappedByteBuffer。

    private static void writeDemo() {
        System.out.println("[writeDemo] start");
        String inputStr = "This write demo. 维多利亚女王纪念碑是位于英国伦敦的一座大型纪念碑和雕塑组合,建于1911年。";
        byte[] inputBytes = inputStr.getBytes();
        final int length = inputBytes.length;
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile("out/writeDemo.txt", "rw");
            MappedByteBuffer mappedByteBuffer = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
            mappedByteBuffer.put(inputBytes);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        System.out.println("[writeDemo] end");
    }
    private static void writeAppendDemo() {
        System.out.println("[writeAppendDemo] start");
        String appendText = "\nThis is append text. 纪念碑的基座由2300吨汉白玉构成。";
        byte[] bytes = appendText.getBytes();
        final int length = bytes.length;
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile("out/writeDemo.txt", "rw");
            MappedByteBuffer mappedByteBuffer = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE, randomAccessFile.length(), length);
            mappedByteBuffer.put(bytes);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        System.out.println("[writeAppendDemo] end");
    }

Android中使用MappedByteBuffer写入文件。记住当前写文件的位置gCurrentLogPos,处理文件增长的问题。

File dir = new File(logFileDir);
if (!dir.exists()) {
    boolean mk = dir.mkdirs();
    Log.d(defTag, "make dir " + mk);
}
File eFile = new File(logFileDir + File.separator + fileName);
byte[] strBytes = logContent.getBytes();
try {
    RandomAccessFile randomAccessFile = new RandomAccessFile(eFile, "rw");
    MappedByteBuffer mappedByteBuffer;
    final int inputLen = strBytes.length;
    if (!eFile.exists()) {
        boolean nf = eFile.createNewFile();
        Log.d(defTag, "new log file " + nf);
        mappedByteBuffer = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE, gCurrentLogPos, LOG_FILE_GROW_SIZE);
    } else {
        mappedByteBuffer = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE, gCurrentLogPos, inputLen);
    }
    if (mappedByteBuffer.remaining() < inputLen) {
        mappedByteBuffer = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE, gCurrentLogPos, LOG_FILE_GROW_SIZE + inputLen);
    }
    mappedByteBuffer.put(strBytes);
    gCurrentLogPos += inputLen;
} catch (Exception e) {
    Log.e(defTag, "WriteRunnable run: ", e);
    if (!eFile.exists()) {
        boolean nf = eFile.createNewFile();
        Log.d(defTag, "new log file " + nf);
    }
    FileOutputStream os = new FileOutputStream(eFile, true);
    os.write(logContent.getBytes());
    os.flush();
    os.close();
}