okio icon indicating copy to clipboard operation
okio copied to clipboard

Source#readZip()

Open vanniktech opened this issue 1 year ago • 5 comments

Counterpart of what I wrote here https://github.com/square/okio/issues/1442#issuecomment-2024801707

When the user is choosing for instance on Android from the file picker a file, I can get an InputStream quite easily. Which I can also call source() on but from there I don't get an easy way of reading it as a zip file. I could as a workaround write it to a file and then call openZip() but I think it's beneficial to have a readZip() directly on a Source so that any source is readable as a Zip.

vanniktech avatar Mar 28 '24 09:03 vanniktech

Unfortunately the thing we need to read a zip FileSystem isn’t a Source (streaming) but rather a FileHandle (random access).

swankjesse avatar Mar 28 '24 11:03 swankjesse

That makes sense. Does InputStream have random access? If not, how is ZipInputStream able to use an InputStream?

vanniktech avatar Mar 28 '24 11:03 vanniktech

ZipInputStream reads valid entries from the beginning of the stream through to the end. Only once at the end do you reach the central index and can realize that some of the entities you saw were not in the directory and thus were old/fake/malicious.

JakeWharton avatar Mar 28 '24 12:03 JakeWharton

Still worth doing, in my opinion, as it has its uses too. Just gotta put a big caveat.

JakeWharton avatar Mar 28 '24 12:03 JakeWharton

Is this a drawback of having layered Sources as opposed to typed InputStreams? A FileInputStream allows us to access FileDescriptor etc: https://developer.android.com/reference/java/io/FileInputStream#getFD()

The reason I mention this is because looking at AssetFileSystem, all calls to the underlying AssetManager.open() use default accessMode AssetManager.ACCESS_STREAMING and so we lose the ability of random access. The source API calls don't have a concept of random access mode, so the only options would be for AssetManager.asFileSystem() to take a Boolean to indicate whether all open() calls should be random access of not, and that would feel a little hacky.

Or alternatively, FileSystem.source() could have an extra argument preferRandomAccess with default value false.

marcardar avatar Dec 26 '24 06:12 marcardar