Reads a file and puts its content into a byte buffer, using the given length and offset. - Java java.nio

Java examples for java.nio:ByteBuffer Read

Description

Reads a file and puts its content into a byte buffer, using the given length and offset.

Demo Code


//package com.java2s;
import java.io.IOException;
import java.nio.ByteBuffer;

import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel;
import static java.nio.channels.FileChannel.MapMode.*;
import java.nio.file.Path;
import static java.nio.file.StandardOpenOption.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static final ByteBuffer EMPTY = ByteBuffer.allocate(0);
    private static final int DIRECT_THRESHOLD = 10240;

    /**//from   w ww . j av a 2s.  co  m
     * Reads a file and puts its content into a byte buffer, using the given length
     * and offset.
     * 
     * @param path
     * @param offset
     * @param length
     * @return
     * @throws IOException 
     */
    public static ByteBuffer load(Path path, int offset, int length)
            throws IOException {
        try (FileChannel fc = FileChannel.open(path, READ)) {
            int size = truncateLength(fc, length);
            ByteBuffer bb = allocate(size);

            fc.position(offset);
            fc.read(bb);
            bb.flip();

            return bb;
        }
    }

    /**
     * Reads a file and puts its whole content into a byte buffer. If the file is
     * larger than {@link java.lang.Integer#MAX_VALUE}, then all bytes beyond
     * that limit are omitted.
     * 
     * @param path
     * @return
     * @throws IOException 
     */
    public static ByteBuffer load(Path path) throws IOException {
        return load(path, 0, -1);
    }

    /**
     * Reads a list of files and puts their contents into a byte buffer. The
     * combined size of all files must not exceed {@link java.lang.Integer#MAX_VALUE}.
     * 
     * @param paths
     * @return
     * @throws IOException 
     */
    public static ByteBuffer load(List<Path> paths) throws IOException {
        List<ByteBuffer> bbs = new ArrayList<>();

        for (Path path : paths) {
            bbs.add(openReadOnly(path));
        }

        return concat(bbs);
    }

    private static int truncateLength(FileChannel fc, int length)
            throws IOException {
        return (int) Math.min(length > 0 ? length : fc.size(),
                Integer.MAX_VALUE);
    }

    public static ByteBuffer allocate(int size) {
        // allocateDirect is pretty slow when used frequently, use it for larger
        // buffers only
        if (size > DIRECT_THRESHOLD) {
            return ByteBuffer.allocateDirect(size);
        } else {
            try {
                return ByteBuffer.allocate(size);
            } catch (OutOfMemoryError ex) {
                // not enough space in the heap, try direct allocation instead
                return ByteBuffer.allocateDirect(size);
            }
        }
    }

    /**
     * Maps a portion of a file to memory and returns the mapped read-only byte
     * buffer using the given offset and length.
     * 
     * @param path
     * @param offset
     * @param length
     * @return
     * @throws IOException 
     */
    public static MappedByteBuffer openReadOnly(Path path, int offset,
            int length) throws IOException {
        try (FileChannel fc = FileChannel.open(path, READ)) {
            return fc.map(READ_ONLY, offset, truncateLength(fc, length));
        }
    }

    /**
     * Maps the whole file to memory and returns the mapped read-only byte buffer.
     * If the file is larger than {@link java.lang.Integer#MAX_VALUE}, then all
     * bytes beyond that limit are omitted.
     * 
     * @param path
     * @return
     * @throws IOException 
     */
    public static MappedByteBuffer openReadOnly(Path path)
            throws IOException {
        return openReadOnly(path, 0, -1);
    }

    /**
     * Concatenates one or more byte buffers to one large buffer. The combined
     * size of all buffers must not exceed {@link java.lang.Integer#MAX_VALUE}.
     * 
     * @param bbs list of byte buffers to combine
     * @return byte buffer containing the combined content of the supplied byte
     *         buffers
     */
    public static ByteBuffer concat(List<ByteBuffer> bbs) {
        long length = 0;

        // get amount of remaining bytes from all buffers
        for (ByteBuffer bb : bbs) {
            bb.rewind();
            length += bb.remaining();
        }

        if (length > Integer.MAX_VALUE) {
            throw new IllegalArgumentException(
                    "Buffers are too large for concatenation");
        }

        if (length == 0) {
            // very funny
            return EMPTY;
        }

        ByteBuffer bbNew = ByteBuffer.allocateDirect((int) length);

        // put all buffers from list
        for (ByteBuffer bb : bbs) {
            bb.rewind();
            bbNew.put(bb);
        }

        bbNew.rewind();

        return bbNew;
    }

    /**
     * Concatenates one or more byte buffers to one large buffer. The combined
     * size of all buffers must not exceed {@link java.lang.Integer#MAX_VALUE}.
     * 
     * @param bb one or more byte buffers to combine
     * @return byte buffer containing the combined content of the supplied byte
     *         buffers
     */
    public static ByteBuffer concat(ByteBuffer... bb) {
        return concat(Arrays.asList(bb));
    }
}

Related Tutorials