-3

I'm trying to read bytes from a file "A". I'm using a RandomAccessFile to seek a position and then I need to read "y" bytes.

I have a buffer of 4096 bytes and if the "y" is not multiple of 4096, I read more bytes than I should.

If I set the buffer to 1 byte, I can read and write without any problem (but, of course, it is too slow).

The code that I have at the moment is:

public void extractFile(int pos) {
    try {
        RandomAccessFile raf = new RandomAccessFile(this.archive, "r");

        /* Trying to read */
        raf.seek(arquivos.get(pos).getPosicaoInicio());
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
        byte[] buf = new byte[1]; // With 1 I can read, because every "y" is multiple of 1
        byte[] bytes;
        while (byteOutput.size() < arquivos.get(pos).getTamanho()) {
            byteOutput.write(buf, 0, raf.read(buf));
        } 
        bytes = byteOutput.toByteArray();
        byteOutput.close();
        raf.close();

        /* Writing */
        File futuroArquivo = new File(arquivos.get(pos).getNome());
        FileOutputStream fos = new FileOutputStream(futuroArquivo);
        fos.write(bytes);
        fos.flush();
        fos.close();

    } catch (IOException ex) {

    }
}

PS: The "arquivos.get(pos).getTamanho()" is my "y"

PS 2: I can't read the whole file, beacuse after the "y" bytes, there are other things

Rafael Tavares
  • 5,678
  • 4
  • 32
  • 48
  • 1
    Have you considered using [`RandomAccessFile.read(byte[] buffer, int offset, int length)`](https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#read-byte:A-int-int-)? – user207421 Nov 12 '17 at 01:22

1 Answers1

2

The buffer can be any size above zero, and the ByteArrayOutputStream is literally a waste of time. And space. You're assuming that read() fills the buffer, too. A better way to write it would be:

RandomAccessFile raf = new RandomAccessFile(this.archive, "r");

/* Trying to read */
raf.seek(arquivos.get(pos).getPosicaoInicio());
byte[] buf = new byte[8192]; // or more, whatever you like really

/* Writing */
File futuroArquivo = new File(arquivos.get(pos).getNome());
FileOutputStream fos = new FileOutputStream(futuroArquivo);
int count;
long rest = arquivos.get(pos).getTamanho();
while (rest > 0 && (count = raf.read(buf, 0, (int)Math.min(buf.length, rest))) > 0)
{
    fos.write(buf, 0, count);
    rest -= count;
}
fos.close();
raf.close();

I would also consider using a BufferedInputStream around a FileInputStream for this, instead of a RandomAccessFile. You're not really doing random access, just an initial seek or skip.

user207421
  • 305,947
  • 44
  • 307
  • 483