繁体   English   中英

Java如何从指定的字节位置读取文件的一部分?

[英]Java how to read part of file from specified position of bytes?

我有一种情况,我需要从指定的字节位置开始仅读取文件的一部分。

我尝试下一个:

protected void writePartToStream(final InputStream in, final OutputStream out, long startBytes) {
        final byte[] b = new byte[BUFFER_SIZE];
        int count = 0;
        amountWritten = startBytes;


        // skip logic
        // how to skip???

        do {
            // write to the output stream
            try {


                out.write(b, 0, count);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }

            amountWritten += count;
            System.out.println("Amount writtent=" + amountWritten);
            // read more bytes from the input stream
            try {
                count = in.read(b, (int) amountWritten, b.length);
            } catch (IOException e) {
            }
        } while (count != -1 && !getStatus().equals(Status.cancelled));

        // the connection was likely terminated abrubtly if these are not equal
        if (!getStatus().equals(Status.cancelled) && getError() == Error.none
                && amountWritten != fileSize) {
            setStatus(Status.error);
            this.error = Error.connection;
        }
    }

但是我从不使用I / O,所以我不知道如何从指定位置开始读取文件。

另一个机会是使用文件的Channel直接从任何位置读取值,如以下示例所示:

int amountBytesToRead = 1337;
int positionToRead = 4211;
FileInputStream fis = new FileInputStream("test.txt");

//A direct ByteBuffer should be slightly faster than a 'normal' one for IO-Operations
ByteBuffer bytes = ByteBuffer.allocateDirect(amountBytesToRead);
fis.getChannel().read(bytes, positionToRead);

byte[] readBytes = bytes.array();
//Handle Bytes

看一看java.io.RandomAccessFile.seek() 它允许从任意位置读取文件,但是其构造函数需要文件名或File对象,而不仅仅是您的方法当前接收的输入流。

您可以设置文件中的位置的FileInputStream使用FileChannel.position(long)FileChannel

FileInputStream fis = ...
long offset = ...
fis.getChannel().position(offset);

// read data from fis

改用FileInputStream.getChannel()。read(ByteBuffer,long potion)

此方法不修改文件当前位置

static class FileInputStreamNoModifyCurrentPosition extends InputStream {
    private long mCurrentPosition;
    private long mRemaining;
    private final FileInputStream mFileInputStream;

    public FileInputStreamNoModifyCurrentPosition(FileInputStream fileInputStream, long offset, long length) throws IOException {
        mFileInputStream = fileInputStream;
        mCurrentPosition = offset;
        mRemaining = length;
    }

    @Override
    public int available() throws IOException {
        return (int) mRemaining;
    }

    @Override
    public int read() throws IOException {
        byte[] buffer = new byte[1];
        if (read(buffer) > 0) {
            return (int) buffer[0] & 0xFF;
        } else {
            return -1;
        }
    }

    @Override
    public int read(byte[] buffer, int offset, int count) throws IOException {
        if (mRemaining >= 0) {
            int readCount = mFileInputStream.getChannel().read(ByteBuffer.wrap(buffer, offset, (int) Math.min(count, mRemaining)), mCurrentPosition);
            if (readCount > 0) {
                skip(readCount);
            }
            return readCount;
        }
        return -1;
    }

    @Override
    public int read(byte[] buffer) throws IOException {
        return read(buffer, 0, buffer.length);
    }

    @Override
    public long skip(long count) throws IOException {
        mCurrentPosition += count;
        mRemaining -= count;
        return count;
    }

    @Override
    public void mark(int readlimit) {
        super.mark(readlimit);
    }

    @Override
    public boolean markSupported() {
        return super.markSupported();
    }

    @Override
    public synchronized void reset() throws IOException {
        super.reset();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM