Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read a segment of a file in Java / Android

I'm sure this might be a simple question, but unfortunately this is my first time using Java and working the Android SDK.

I am uploading files on Android using the Apache HTTP libraries, in particular using the MultipartEntity.

I'm uploading to a service that allows me to send them chunks of the file, and once complete, they'll reassemble the chunks. I'd like to take advantage of this feature.

Here's the scenario.

File FOO.BAR is 20 MB. I'd split it into some arbitrary chunk size, let's say 1 MB, which means 20 chunks. Chunks #3 and #14 fail (maybe the cellular/WiFi connection was bad). I can now re-upload just these two chunks and everything will be good.

What I'd like to know is how can I read only part of a file (like the data between 3MB and 4MB)?

The file piece should be an InputStream or File object.

Thanks, Makoto

like image 516
Makotosan Avatar asked Aug 27 '10 04:08

Makotosan


1 Answers

You can either use the skip(long) method to skip the number of bytes in the InputStream or you can create a RandomAccessFile on the File object and call its seek(long) method to set the pointer to that position so you can start reading from there.

The quick test below reads in a 4mb+ file (between 3m and 4mb) and writes the read data to an ".out" file.

import java.io.*;
import java.util.*;

public class Test {

    public static void main(String[] args) throws Throwable {
       long threeMb = 1024 * 1024 * 3;
       File assembled =  new File(args[0]); // your downloaded and assembled file
       RandomAccessFile raf = new RandomAccessFile(assembled, "r"); // read
       raf.seek(threeMb); // set the file pointer to 3mb
       int bytesRead = 0;
       int totalRead = 0;
       int bytesToRead = 1024 * 1024; // 1MB (between 3M and 4M

       File f = new File(args[0] + ".out");
       FileOutputStream out = new FileOutputStream(f);

       byte[] buffer = new byte[1024 * 128]; // 128k buffer 
       while(totalRead < bytesToRead) { // go on reading while total bytes read is
                                        // less than 1mb
         bytesRead = raf.read(buffer);
         totalRead += bytesRead;
         out.write(buffer, 0, bytesRead);
         System.out.println((totalRead / 1024));
       }
    }
}
like image 162
naikus Avatar answered Sep 28 '22 09:09

naikus