@@ -8,15 +8,16 @@ import (
8
8
"os"
9
9
"path"
10
10
"sync"
11
+ "path/filepath"
11
12
12
13
"file-compressor/utils"
13
14
)
14
15
15
- // Compress compresses the specified files into a single compressed file.
16
+ // Compress compresses the specified files or folders into a single compressed file.
16
17
func Compress (filenameStrs []string , outputDir * string , password * string ) error {
17
- // Check if there are files to compress
18
+ // Check if there are files or folders to compress
18
19
if len (filenameStrs ) == 0 {
19
- return errors .New ("no files to compress" )
20
+ return errors .New ("no files or folders to compress" )
20
21
}
21
22
22
23
// Set default output directory if not provided
@@ -34,30 +35,39 @@ func Compress(filenameStrs []string, outputDir *string, password *string) error
34
35
// Channel to receive errors from goroutines
35
36
errChan := make (chan error , len (filenameStrs ))
36
37
37
- // Read files and store their content concurrently
38
+ // Process each input file or folder
38
39
for _ , filename := range filenameStrs {
39
40
wg .Add (1 )
40
41
go func (filename string ) {
41
42
defer wg .Done ()
42
43
43
- // Check if the file exists
44
- if _ , err := os .Stat (filename ); os .IsNotExist (err ) {
45
- errChan <- fmt .Errorf ("file does not exist: %s" , filename )
44
+ // Check if the file or folder exists
45
+ info , err := os .Stat (filename )
46
+ if os .IsNotExist (err ) {
47
+ errChan <- fmt .Errorf ("file or folder does not exist: %s" , filename )
46
48
return
47
49
}
48
50
49
- // Read file content
50
- content , err := os .ReadFile (filename )
51
- if err != nil {
52
- errChan <- fmt .Errorf ("failed to read file %s: %w" , filename , err )
53
- return
51
+ // Handle directory recursively
52
+ if info .IsDir () {
53
+ err := compressFolderRecursive (filename , & files )
54
+ if err != nil {
55
+ errChan <- err
56
+ }
57
+ } else {
58
+ // Read file content
59
+ content , err := os .ReadFile (filename )
60
+ if err != nil {
61
+ errChan <- fmt .Errorf ("failed to read file %s: %w" , filename , err )
62
+ return
63
+ }
64
+
65
+ // Store file information (name and content)
66
+ files = append (files , utils.File {
67
+ Name : path .Base (filename ),
68
+ Content : content ,
69
+ })
54
70
}
55
-
56
- // Store file information (name and content)
57
- files = append (files , utils.File {
58
- Name : path .Base (filename ),
59
- Content : content ,
60
- })
61
71
}(filename )
62
72
}
63
73
@@ -95,8 +105,42 @@ func Compress(filenameStrs []string, outputDir *string, password *string) error
95
105
return nil
96
106
}
97
107
108
+ // Function to recursively compress a folder and its contents
109
+ func compressFolderRecursive (folderPath string , files * []utils.File ) error {
110
+ // Traverse the folder contents
111
+ err := filepath .Walk (folderPath , func (filePath string , info os.FileInfo , err error ) error {
112
+ if err != nil {
113
+ return err
114
+ }
115
+ if ! info .IsDir () {
116
+ // Read file content
117
+ content , err := os .ReadFile (filePath )
118
+ if err != nil {
119
+ return fmt .Errorf ("failed to read file %s: %w" , filePath , err )
120
+ }
121
+
122
+ filename , err := filepath .Rel (folderPath , filePath )
123
+ if err != nil {
124
+ return fmt .Errorf ("failed to get relative path for file %s: %w" , filePath , err )
125
+ }
126
+
127
+ // Store file information (relative path and content)
128
+ * files = append (* files , utils.File {
129
+ Name : filepath .ToSlash (filename ), // Store relative path
130
+ Content : content ,
131
+ })
132
+ }
133
+ return nil
134
+ })
135
+
136
+ if err != nil {
137
+ return fmt .Errorf ("error compressing folder %s: %w" , folderPath , err )
138
+ }
98
139
99
- // Decompress decompresses the specified compressed file into individual files.
140
+ return nil
141
+ }
142
+
143
+ // Decompress decompresses the specified compressed file into individual files or folders.
100
144
func Decompress (filenameStrs []string , outputDir * string , password * string ) error {
101
145
// Check if there are files to decompress
102
146
if len (filenameStrs ) == 0 {
@@ -135,13 +179,22 @@ func Decompress(filenameStrs []string, outputDir *string, password *string) erro
135
179
// Channel to receive errors from goroutines
136
180
errChan := make (chan error , len (files ))
137
181
138
- // Write decompressed files to the output directory concurrently
182
+ // Process each decompressed file
139
183
for _ , file := range files {
140
184
wg .Add (1 )
141
185
go func (file utils.File ) {
142
186
defer wg .Done ()
143
187
144
- err := os .WriteFile (* outputDir + "/" + file .Name , file .Content , 0644 )
188
+ // Create directories if they don't exist
189
+ outputPath := filepath .Join (* outputDir , filepath .Dir (file .Name ))
190
+ err := os .MkdirAll (outputPath , os .ModePerm )
191
+ if err != nil {
192
+ errChan <- fmt .Errorf ("failed to create directory %s: %w" , outputPath , err )
193
+ return
194
+ }
195
+
196
+ // Write decompressed file content
197
+ err = os .WriteFile (filepath .Join (* outputDir , file .Name ), file .Content , 0644 )
145
198
if err != nil {
146
199
errChan <- fmt .Errorf ("failed to write decompressed file %s: %w" , file .Name , err )
147
200
return
0 commit comments