Work with files and directories in the archive.
Internal.Format.Entry
Represents a file or a directory in a Zip
archive.
You can use this to extract the content and read the metadata.
See Entry.path
to learn more about the way these entries are stored.
toString : Entry -> Result ExtractError String
Extract the content of an Entry
as a String
.
toBytes : Entry -> Result ExtractError Bytes
Extract the content of an Entry
as Bytes
.
Bytes can represent an image, a PDF, a ZIP within a ZIP, anything you can imagine.
Examples of what you can do with Bytes
:
File.Download.bytes
to download them as a file.Http.bytesBody
to send them to an HTTP server.elm/bytes
package to decode these bytes into any data structure.Extracting content from an entry might fail if:
path : Entry -> String
Get the absolute path of an entry.
path dir == "versions/"
path v1 == "versions/v1.txt"
path v2 == "versions/v2.txt"
Even though Zip archives are aware of directories, they do not store entries in a tree format. Instead, each entry simply indicates its absolute path in the archive.
Different applications have different needs and they may or may not care about the tree structure.
Some applications might expect a certain structure and can simply use Zip.getEntry
to get the
relevant entries.
Other applications might want to explore the archive, and can use Zip.entries
to get a list of the entries and go from there.
basename : Entry -> String
Get the final component of an entry's path.
basename v1 == "v1.txt"
path v1 == "versions/v1.txt"
extractedSize : Entry -> Basics.Int
Get the uncompressed size of an entry.
This is the number of bytes that you will get if you extract this entry.
compressedSize : Entry -> Basics.Int
Get the compressed size of an entry as stored in the archive.
lastModified : Time.Zone -> Entry -> Time.Posix
Get the last time an entry was modified.
Zip time stamps are relative to the time zone they were created in. However, the time zone is not stored in the archive. This means you need to know the zone to get a meaningful time stamp.
isDirectory : Entry -> Basics.Bool
Determine if an entry is a directory.
comment : Entry -> String
Get the comment of an entry.
checksum : Entry -> Basics.Int
Get the CRC32 checksum of an entry's uncompressed data.
You don't need to check the integrity of the data, the extract content functions do it for you.
However, you might still find this checksum useful for other purposes, like quickly determining whether two files are identical.
Create archive entries.
{ path : String
, lastModified : ( Time.Zone
, Time.Posix )
, comment : Maybe String
}
Metadata needed to create an entry.
Note: lastModified
requires a Time.Zone
to be provided because ZIP time stamps are not stored in a universal zone (like UTC). Read more above.
When you create a file Entry
you can choose to store the data as-is or compress it.
Keep in mind that:
Hopefully that helps you decide whether you need compression or not.
store : Meta -> Bytes -> Entry
Create an entry for a file without compressing it.
import Bytes.Encode as Encode
helloTxt =
Encode.string "Hello, World!"
|> Encode.encode
|> store
{ path = "hello.txt"
, lastModified = ( zone, now )
, comment = Nothing
}
Files inside directories are created by passing the absolute path:
store
{ path = "versions/v1.txt"
, lastModified = ( zone, now )
, comment = Nothing
}
compress : Meta -> Bytes -> Entry
Compress a file with Deflate and create an entry out of it.
Besides compression, it works just like store
.
createDirectory : Meta -> Entry
Create a directory entry.
You do not need to explicitly create directories. Extracting programs automatically create directories in the path to a file.
Use this if you need to add directory metadata or if you want a directory to exist even if it doesn't contain any files.
Deflate compression is provided by
folkertdev/elm-flate
.
Most archives you'll find in the wild will use this method.
If you're expecting to work with archives using other methods, you can handle them by using the method number
and raw bytes from the UnsupportedCompression
case.
case toBytes entry of
Err (UnsupportedCompression 6 rawBytes) ->
Ok <| decodeImplode rawBytes
result ->
result
You can read more about compression methods and their corresponding numbers in section 4.4.5 of the specification.