Fantom has a pretty cool API for inspecting zip files and streams, but sometimes you just want to zip up a directory, or unzip a file. These handy little methods let you do just that.
** A collection of Zip / File utilities.
class ZipUtils {
** Compresses the given file and returns the compressed .zip file.
** 'toCompress' may be a directory.
**
** If 'destFile' is null, it defaults to '${toCompress.basename}.zip'
**
** The options map is used to customise zipping:
** - bufferSize: an 'Int' that defines the stream buffer size. Defaults to 16Kb.
** - incFolderName: set to 'true' to include the containing folder name in the zip path
**
static File zip(File toCompress, File? destFile := null, [Str:Obj]? options := null) {
if (destFile != null && destFile.isDir)
throw ArgErr("Destination can not be a directory - ${destFile}")
bufferSize := options?.get("bufferSize") ?: 16*1024
dstFile := destFile ?: toCompress.parent + `${toCompress.basename}.zip`
zip := Zip.write(dstFile.out(false, bufferSize))
parentUri := toCompress.isDir && options?.get("incFolderName") == true ? toCompress.parent.uri : toCompress.uri
try {
toCompress.walk |src| {
if (src.isDir) return
path := src.uri.relTo(parentUri)
out := zip.writeNext(path)
try {
src.in(bufferSize).pipe(out)
} finally
out.close
}
} finally
zip.close
return dstFile
}
** Decompresses the given file and returns the directory it was unzipped to.
**
** The options map is used to customise zipping:
** - bufferSize: an 'Int' that defines the stream buffer size. Defaults to 16Kb.
**
static File unzip(File toDecompress, File? destDir := null, [Str:Obj]? options := null) {
if (toDecompress.isDir)
throw ArgErr("Destination can not be a directory - ${toDecompress}")
if (destDir != null && !destDir.isDir)
throw ArgErr("Destination must be a directory - ${destDir}")
bufferSize := options?.get("bufferSize") ?: 16*1024
dstDir := destDir ?: toDecompress.parent
zip := Zip.read(toDecompress.in(bufferSize))
try {
File? entry
while ((entry = zip.readNext) != null) {
entry.copyTo(dstDir + entry.uri.relTo(`/`), ["overwrite":true])
}
} finally {
zip.close
}
return dstDir
}
** Create a temporary directory which is guaranteed to be a new, empty
** directory with a unique name. The dir name will be generated using
** the specified prefix and suffix.
**
** If dir is non-null then it is used as the file's parent directory,
** otherwise the system's default temporary directory is used.
**
** Examples:
** File.createTemp("x", "-etc") => `/tmp/x67392-etc/`
** File.createTemp.deleteOnExit => `/tmp/fan-5284/`
**
** See the Fantom forum topic [File.createTempDir()]`http://fantom.org/forum/topic/2424`.
**
static File createTempDir(Str prefix := "fan-", Str suffix := "", File? dir := null) {
tempFile := File.createTemp(prefix, suffix, dir ?: Env.cur.tempDir)
dirName := tempFile.name
tempFile.delete
tempDir := tempFile.parent.createDir(dirName)
return tempDir
}
}
I've used them myself a couple of times... thought it maybe useful to share.
brianThu 27 Aug 2015
If you are working a build script, you can use build::CreateZip task
SlimerDude Tue 25 Aug 2015
Fantom has a pretty cool API for inspecting
zip filesand streams, but sometimes you just want to zip up a directory, or unzip a file. These handy little methods let you do just that.Code is also available as a BitBucket Snippet.
** A collection of Zip / File utilities. class ZipUtils { ** Compresses the given file and returns the compressed .zip file. ** 'toCompress' may be a directory. ** ** If 'destFile' is null, it defaults to '${toCompress.basename}.zip' ** ** The options map is used to customise zipping: ** - bufferSize: an 'Int' that defines the stream buffer size. Defaults to 16Kb. ** - incFolderName: set to 'true' to include the containing folder name in the zip path ** static File zip(File toCompress, File? destFile := null, [Str:Obj]? options := null) { if (destFile != null && destFile.isDir) throw ArgErr("Destination can not be a directory - ${destFile}") bufferSize := options?.get("bufferSize") ?: 16*1024 dstFile := destFile ?: toCompress.parent + `${toCompress.basename}.zip` zip := Zip.write(dstFile.out(false, bufferSize)) parentUri := toCompress.isDir && options?.get("incFolderName") == true ? toCompress.parent.uri : toCompress.uri try { toCompress.walk |src| { if (src.isDir) return path := src.uri.relTo(parentUri) out := zip.writeNext(path) try { src.in(bufferSize).pipe(out) } finally out.close } } finally zip.close return dstFile } ** Decompresses the given file and returns the directory it was unzipped to. ** ** The options map is used to customise zipping: ** - bufferSize: an 'Int' that defines the stream buffer size. Defaults to 16Kb. ** static File unzip(File toDecompress, File? destDir := null, [Str:Obj]? options := null) { if (toDecompress.isDir) throw ArgErr("Destination can not be a directory - ${toDecompress}") if (destDir != null && !destDir.isDir) throw ArgErr("Destination must be a directory - ${destDir}") bufferSize := options?.get("bufferSize") ?: 16*1024 dstDir := destDir ?: toDecompress.parent zip := Zip.read(toDecompress.in(bufferSize)) try { File? entry while ((entry = zip.readNext) != null) { entry.copyTo(dstDir + entry.uri.relTo(`/`), ["overwrite":true]) } } finally { zip.close } return dstDir } ** Create a temporary directory which is guaranteed to be a new, empty ** directory with a unique name. The dir name will be generated using ** the specified prefix and suffix. ** ** If dir is non-null then it is used as the file's parent directory, ** otherwise the system's default temporary directory is used. ** ** Examples: ** File.createTemp("x", "-etc") => `/tmp/x67392-etc/` ** File.createTemp.deleteOnExit => `/tmp/fan-5284/` ** ** See the Fantom forum topic [File.createTempDir()]`http://fantom.org/forum/topic/2424`. ** static File createTempDir(Str prefix := "fan-", Str suffix := "", File? dir := null) { tempFile := File.createTemp(prefix, suffix, dir ?: Env.cur.tempDir) dirName := tempFile.name tempFile.delete tempDir := tempFile.parent.createDir(dirName) return tempDir } }I've used them myself a couple of times... thought it maybe useful to share.
brian Thu 27 Aug 2015
If you are working a build script, you can use
build::CreateZiptask