To protect and secure files, files are zipped and compressed.
However, there is a need to unzip files for their usage.
The .ZIP
extension is the standard file extension for compressed files. However, there are other file extensions used for zipped files which include the following formats:
.JAR
.WAR
.DOCX
.ODS
.ODP
Go’s standard library has a package called "archive/zip"
. This package is used for compressing and decompressing files.
Before delving into unzipping a file, there are core components that help us achieve this. Go’s standard library provides all the packages needed without the need to import an external library. We will be using five packages to achieve this. The packages are:
os
packageio
packagearchive/zip
packagepath/filepath
packagefmt
packagezip.OpenReader
functionTo unzip a file, the first thing to be done is to open the file. The zip.OpenReader
handles this for us. So how does this function work?
The OpenReader
function takes care of opening the zip file specified by it’s name and returns *ReadCloser
and an error
.
// The zip.OpenReader functionfunc OpenReader(name string) (*ReadCloser, error)//The zip.Reader typetype Reader struct{File []*FileComment string}
reader
After the zip file is opened, it returns *ReadCloser
which is an instance of zip.Reader
. zip.Reader
is a struct that has the field File
of type []*zip.File
and field Comment
of type string
.
A head start in the unzipping process is to name the destination folder to save the file to be unzipped.
The file destinationFolder
is declared as "unzipFolder"
.
package mainimport ("fmt""archive/zip""io""os""path/filepath")func main() {fileDestinationFolder := "unzipFolder"//The first thing is to open the zipped file.openedFile, err := zip.OpenReader("unzip/archive.zip")if err != nil{panic(err)}// postpone the closing of the file.defer openedFile.Close()}
zip.OpenReader
function which takes in a parameter of the link to the folder where the zipped file folder is located.
This returns an error
and the instance of zip.Reader
. In the code above, it is named openedFile
. This is a slice of type File
.package mainimport ("fmt""archive/zip""io""os""path/filepath")func main() {for _, file := range openedFile.File{filePath := filepath.Join(destinationFolder,file.Name)fmt.Println("unzipping file", filePath)// if the file is an empty directory, create a directoryif file.FileInfo().IsDir(){// create the directoryos.MkdirAll(filePath,os.ModePerm)continue}}
The openFile
, which is a slice of type File
, is looped through using the range
method to get an individual file.
Using the filepath.Join()
method, the destinationfolder
and the file.Name
are joined into a single path named filePath
. This is where the unzipping process starts.
After this is done, the next step is to create a directory. This is achieved using the os.MkdirAll()
method, if the file is in an empty directory.
if err := os.MkdirAll(filepath.Dir(filePath),os.ModePerm); err != nil{panic(err)}else {destinationFile, err := os.OpenFile(filePath,os.O_CREATE|os.O_WRONLY|os.O_TRUNC,file.Mode())if err != nil{panic(err)}//Opening the file and copy it's contentsfileInArchive, err := file.Open()if err != nil{}if _, err := io.Copy(destinationFile,fileInArchive); err != nil{panic(err)}destinationFile.Close()fileInArchive.Close()}}}
The next condition checks if the file is within a directory.
If these two conditions fail, then it opens the filePath
using the os.Openfile()
method.
Theos.O_CREATE
creates a file if the file does not exist in the destination folder.
Theos.O_WRONLY
opens the file in a write-only mode
and os.O_TRUNC
truncates the file when opened. Any of these could happen since it is executed by an OR
operator.
This operation returns an error
and thedestinationFile
of type *file
. The error
is handled.
The final step is to open the contents of the file saved as fileInAchived
. This is copied into thedestinationFile
using the io
package.
GOROOT=/usr/local/go #gosetupGOPATH=/Users/decagon/go #gosetup/usr/local/go/bin/go build -o /private/var/folders/8w/g4zndjnj2yl3p12p3ht_hryc0000gn/T/GoLand/___go_build_espresso_unzip espresso/unzip #gosetup/private/var/folders/8w/g4zndjnj2yl3p12p3ht_hryc0000gn/T/GoLand/___go_build_espresso_unzipopen zip archiveunzipping file unzipFolder/csv/test.csvProcess finished with the exit code 0
Uncompressing the "unzip/archive.zip"
file requires us to create a destinationFolder
. The zipped file was opened with the openReader
function. The openReader
function returns an instance of zip.Reader
and an error
. The zip.Reader
is a struct that contains a field File
of type []*zip.File
and a Comment
of type String
.
The derived file is a slice. To get the individual file, we had to loop it and join the file name with the destinationFolder
. We checked if the file was within an empty directory. A directory was created if it failed the conditions. The filePath
was opened using the os.Openfile()
method. The final step was to open the contents of the file saved as fileInAchived
before copying it into thedestinationFile
using the io.Copy
method.
Free Resources