-1

Im accessing a large file on a USB flash drive plugged into Android. Since the file is large, i need to "seek" inside the file rather than load in the whole thing.

In C language, seek is just one line of code, but to accomplish that on android seems to require some epic coding.

I saw this class on the internet that allows you to seek in a stream, but it requires passing a "File Object" to its constructor.

https://github.com/vitalidze/justdlna/blob/master/src/main/java/su/litvak/justdlna/util/RandomAccessFileInputStream.java

Right now the code i have to access the file on the usb drive are:

InputStream in=getContentResolver().openInputStream(uri);

or

ParcelFileDescriptor pfd= getContentResolver().openFileDescriptor(uri,"rw");

But how do i get a File Object from the ContentResolver so i can pass that to RandomAccessFileInputStream class (at the link above)

Tunaki
  • 132,869
  • 46
  • 340
  • 423
programmer3
  • 97
  • 1
  • 12

1 Answers1

1

Im accessing a large file on a USB flash drive plugged into Android

That may be a problem.

Since the file is large, i need to "seek" inside the file rather than load in the whole thing.

That may be a bigger problem.

In C language, seek is just one line of code

Not necessarily.

Right now the code i have to access the file on the usb drive are

I am assuming that you are getting this Uri from ACTION_OPEN_DOCUMENT or some similar API tied into the Storage Access Framework. If so, you will have better luck if you think of the Uri as being an actual URI. URIs, such as a URL, do not necessarily represent local resources and do not necessarily represent something for which "seek is just one line of code".

InputStream offers mark() and reset(), which are the closest things that you have to true random seek capability. And, not every stream will support those — for example, you cannot necessarily reset() a stream backed by a TCP/IP socket.

But how do i get a File Object from the ContentResolver

You don't, other than by using the InputStream to read in the entire content represented by the Uri, writing it out to some FileOutputStream for a File that you control (e.g., on internal storage via getFilesDir()), and then using the resulting file.

Or, see if you can get by with mark() and reset(), also calling markSupported() to see if that is possible with the InputStream (it should be in your case, but I cannot guarantee it).

Or, establish a prerequisite that the file be copied by somebody else off the USB flash drive onto a portion of the device's on-board flash filesystem that you can directly access, such as external storage.

Or, establish a prerequisite that the file be located in a particular location on removable storage that your app has direct filesystem access to (i.e., getExternalFilesDirs(), where the second and subsequent entries in the array are locations on removable media that you can read and write from).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Hello, thanks for your help, yes I can place the file at a fixed location (root) on the external usb drive. As I understand you, if i put the file at a fixed location in the usb, how will i find that file (ex mount point etc) what api will i use to get its location, and open the file for seeking? – programmer3 Jun 18 '16 at 18:19
  • 1
    @dreadlocks: "yes I can place the file at a fixed location (root) on the external usb drive" -- you will not have direct access via the filesystem to the root of the USB drive. You have to put the file where **Android** tells you your app has access. That may vary by device and device user. You find out that location, for that device and user, by plugging in the drive, calling `getExternalFilesDirs()` on a `Context`, and seeing what the second (and subsequent) locations are. This is designed for apps to write their own stuff to the location, then read it back in later, not for your scenario. – CommonsWare Jun 18 '16 at 18:32