Giter Site home page Giter Site logo

Write a .zip about okio HOT 9 OPEN

swankjesse avatar swankjesse commented on July 20, 2024 1
Write a .zip

from okio.

Comments (9)

swankjesse avatar swankjesse commented on July 20, 2024

Maybe something like this?

fun BufferedSink.writeZip(
  sourceFileSystem: FileSystem,
  baseDirectory: Path,
)

You’d create a real or fake FileSystem, populate a directory with content, then create a .zip from that content.

One drawback of this API is it’s awkward to create entries from a stream, like an HTTP response.

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

Another option:

fun BufferedSink.writeZip(
  writeContents: FileSystem.() -> Unit,
)

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

A couple more considerations:

  • A new ZIP-writing API should allow the caller to supply timestamps. These could come from the originating file, or from the clock, or they could be constant 0 values. What’s the convention for zeroing out timestamps in zips? We should do that.

  • A new ZIP-writing API should allow the caller to configure either COMPRESSION_METHOD_DEFLATED or COMPRESSION_METHOD_STORED for each file.

  • For directory entries, we could always include them, always exclude them, let the user choose, or let the user choose on a case-by-case basis.

I suspect these are a deal-breaker for the APIs that use a FileSystem as the input or builder.

Here’s another API proposal. It ends up looking a lot like Moshi’s JsonUtf8Writer in name & usage.

class ZipWriter(sink: BufferedSink) : Closeable {
  inline fun <T> file(
    file: Path,
    compress: Boolean = true,
    lastModifiedAtMillis: Long? = null,
    lastAccessedAtMillis: Long? = null,
    createdAtMillis: Long? = null,
    writerAction: BufferedSink.() -> T,
  ): T

  fun directory(
    dir: Path,
    lastModifiedAtMillis: Long? = null,
    lastAccessedAtMillis: Long? = null,
    createdAtMillis: Long? = null,
  )
}

inline fun <T> BufferedSink.writeZip(writerAction: ZipWriter.() -> T): T

And a usage example of the above:

FileSystem.SYSTEM.write("greetings.zip".toPath()) {
  writeZip {
    file("hello.txt".toPath()) {
      writeUtf8("Hello World")
    }

    directory("directory".toPath())

    directory("directory/subdirectory".toPath())

    file(
      file = "directory/subdirectory/child.txt".toPath(),
      compress = false,
      lastModifiedAtMillis = Clock.System.now().toEpochMilliseconds(),
    ) {
      writeUtf8("Another file!")
    }
  }
}

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

I think I’d canonicalize input paths by stripping a leading / if present. I think that’s more user-friendly than either crashing or creating a .zip file that includes an absolute path.

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

I think I’d default timestamps to null/absent/0 rather than grabbing the host machine’s time and jamming that in there. Too many tools that produce .zip archives end up with non-deterministic outcomes because their libraries inserted data in the output that the author never really asked for.

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

I think I’d produce .zip files that don’t include directory entries at all by default. I’d only add ’em if the user explicitly asked for them. This creates an escape hatch for developers that want empty directories in their .zip files, without creating a bunch of redundant data otherwise.

from okio.

swankjesse avatar swankjesse commented on July 20, 2024

I think I’d stream output to a BufferedSink, which should make it straightforward to create .zip files on-demand in web services or clients.

from okio.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.