java中BufferedInputStream BufferedOutputStream HeapByteBuffer DirectByteBuffer缓冲的区别

在之前写的文章基础上

https://blog.csdn.net/zlpzlpzyd/article/details/135247283

以 1GB 的文件为例比较

200

500

1024(1KB)

2KB

4KB

8KB

16KB

32KB

64KB

128KB

256KB

512KB

1MB

8MB

64MB

128MB

256MB

512MB

BufferedInputStream

761

665

450

448

458

457

282

251

220

204

204

203

487

549

627

723

785

911

HeapByteBuffer

6125

2677

1489

886

605

419

298

251

248

204

251

235

290

282

377

393

454

525

DirectByteBuffer

5786

2526

1419

849

553

380

265

204

173

188

173

173

203

188

219

253

220

292

以 2.45GB 的文件为例比较

200

500

1024(1KB)

2KB

4KB

8KB

16KB

32KB

64KB

128KB

256KB

512KB

1MB

8MB

64MB

128MB

256MB

512MB

BufferedInputStream

1458

1373

872

925

894

848

629

549

502

455

487

456

1098

549

627

723

785

911

HeapByteBuffer

12471

5419

2969

1838

1208

824

630

518

473

470

465

517

290

282

377

393

454

525

DirectByteBuffer

11792

5198

2857

1711

1162

801

514

455

392

361

361

377

203

188

219

253

220

292

由上面的测试结果得知,在缓冲区容量在 8KB、16KB、32KB、64KB、128KB、256KB、512KB 的时候三者耗时持平,但是耗时最短的是 128KB,耗时趋势是开口朝上的抛物线,缓冲区容量达到最佳阈值后再往上增加耗时反而增加。

鉴于 DirectByteBuffer 受限于 jvm 参数 -XX:MaxDirectMemorySize 的大小,默认值为 64MB,在运行时调整为大于 64MB 的缓冲大小后运行时间降低不明显。

BufferedInputStream

在 java 1.0 中添加的缓冲类

验证代码

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;

public class TestBufferedInputStream implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        byte[] bs = new byte[Control.SIZE];
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            while (bis.read(bs) != -1) {
//                    System.out.println(Arrays.toString(bs));
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

java中BufferedInputStream BufferedOutputStream HeapByteBuffer DirectByteBuffer缓冲的区别_第1张图片

HeapByteBuffer

在 java 1.4 中添加的缓冲类

验证代码

import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestHeapByteBuffer implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        ByteBuffer byteBuffer = ByteBuffer.allocate(Control.SIZE);
        try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
            while (fileChannel.read(byteBuffer) > 0) {
                byteBuffer.clear();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

java中BufferedInputStream BufferedOutputStream HeapByteBuffer DirectByteBuffer缓冲的区别_第2张图片

DirectByteBuffer

验证代码

import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestDirectByteBuffer implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Control.SIZE);
        try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
            while (fileChannel.read(byteBuffer) > 0) {
                byteBuffer.clear();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

java中BufferedInputStream BufferedOutputStream HeapByteBuffer DirectByteBuffer缓冲的区别_第3张图片

总结

HeapByteBuffer 和 DirectByteBuffer 是从 java 1.4 开始添加的类,之前的版本处理缓冲问题需要使用 BufferedInputStream 和 BufferedOutputStream,问题是针对 io 操作只能单向处理,HeapByteBuffer 和 DirectByteBuffer 结合 FileChannel 可以实现对文件的双向处理,即可以通过 FileChannel 实现读写功能。

参考链接

https://blog.csdn.net/flyzing/article/details/115388720

你可能感兴趣的:(java,java,nio)