9

I have a situation when I need to read only part of file, beginning from specified byte position.

I try with next :

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;
        }
    }

But I never working with I/O, so I don't have any idea how to start read file, from specified position.

1
  • 1
    FileInputStream has method read(byte[] b, int off, int len) where you can specify start position. Commented Mar 2, 2016 at 11:14

4 Answers 4

9

Another chance is to use the Channel of the file to read values directly from any position as shown in the following example:

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
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. But I got java.lang.UnsupportedOperationException at java.nio.ByteBuffer.array when i used allocateDirect method. It runs fine when allocate method is used.
2

Take a look at java.io.RandomAccessFile.seek(). It allows reading a file from an arbitrary position, but its constructor requires a filename or a File object, not just an input stream as your method currently receives.

1 Comment

Looks like that what I'm looking for. I will try with it and if it helps - I will approve it.
1

You can set the position in the file for a FileInputStream using FileChannel.position(long) of it's FileChannel:

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

// read data from fis

Comments

0

using FileInputStream.getChannel().read(ByteBuffer, long posotion) instead

this method don't modify the file current position

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();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.