Klassenbiliothek fuer Dateiverwaltung
ulrich
2 days ago e1fae256e29eb7a317d5a810d7e24751eb6032eb
commit | author | age
e369b9 1 /*
c45b52 2   fm - File management class library
e369b9 3   Copyright (C) 2024  Ulrich Hilger
U 4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package de.uhilger.fm;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.util.zip.Adler32;
25 import java.util.zip.CheckedOutputStream;
26 import java.util.zip.ZipEntry;
27 import java.util.zip.ZipOutputStream;
28
29 /**
30  * Eine Klasse mit Methoden zum Packen von Dateien #
31  *
32  * @author Ulrich Hilger, 15. Januar 2024
33  */
34 public class Deflator {
8f4ae9 35   
U 36   private final String STR_SLASH = "/";
e369b9 37
U 38   /* --------------- Ordner packen ----------------- */
39   /**
40    * Einen Ordner packen.
41    *
42    * Als Ziel wird eine neue Datei mit Dateiendung '.zip' erzeugt, die so heisst wie der Ordner, der
43    * gapckt werden soll. Die Datei mit dem gepackten Ordnerinhalt wird in dem Ordner angelegt, der
44    * den zu packenden Ordner enthaelt.
45    *
46    * @param fName Name des zu packenden Ordners
47    * @param relPath relativer Pfad zum Ordner, der gepackt werden soll
48    * @return die Meldung mit dem Ergebnis. Wenn die Meldung nicht "ok" lautet wurde die ZIP-Datei
49    * nicht erzeugt und die Meldung nennt den Grund.
50    */
51   public String packFolder(String fName, String relPath, String base/*, HttpExchange e*/) {
52     if (!relPath.startsWith(".")) {
53       try {
54         //String fName = getFileName(e);
55         //logger.fine("fName: " + fName);
8f4ae9 56         if (fName.endsWith(STR_SLASH)) {
e369b9 57           File dir = new File(base, fName);
U 58           if (dir.isDirectory()) {
59             //logger.fine("absPath: " + dir.getAbsolutePath());
60             File parentDir = dir.getParentFile();
61             StringBuilder fname = new StringBuilder();
62             fname.append(dir.getName());
63             fname.append(".zip");
64             File archiveFile = new File(parentDir, fname.toString());
65             pack(dir.getAbsolutePath(), archiveFile.getAbsolutePath());
66             return "ok";
67           } else {
68             return "kein Ordner";
69           }
70         } else {
71           return "kein Ordner";
72         }
73       } catch (Exception ex) {
74         String result = ex.getLocalizedMessage();
75         //logger.log(Level.SEVERE, result, ex);
76         return result;
77       }
78     } else {
79       return "Falsche relative Pfadangabe";
80     }
81   }
82
83   /**
84    * pack the contents of a given folder into a new ZIP compressed archive
85    *
86    * @param folder absolute path and name of the folder to pack
87    * @param archive absolute path and name of the archive to create from the given files
88    * @throws Exception
89    */
90   private boolean pack(String folder, String archive) throws Exception {
91     File file = new File(archive);
92     FileOutputStream fos = new FileOutputStream(file);
93     CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());
94     ZipOutputStream zos = new ZipOutputStream(checksum);
95     pack(zos, folder, "");
96     zos.flush();
97     zos.finish();
98     zos.close();
99     fos.flush();
100     fos.close();
101     return true;
102   }
103
104   /**
105    * go through the given file structure recursively
106    *
107    * @param zipFile the ZIP file to write to
108    * @param srcDir the directory to pack during this cycle
109    * @param subDir the subdirectory to append to names of file entries inside the archive
110    * @throws IOException
111    */
112   private void pack(ZipOutputStream zipFile, String srcDir, String subDir) throws IOException {
113     File[] files = new File(srcDir).listFiles();
114     for (int i = 0; i < files.length; i++) {
115       if (files[i].isDirectory()) {
116         pack(zipFile, files[i].getAbsolutePath(), subDir + File.separator + files[i].getName());
117       } else {
118         packFile(zipFile, subDir, files[i]);
119       }
120     }
121   }
122
123   /**
124    * pack a given file
125    *
126    * @param zipFile the ZIP archive to pack to
127    * @param dir the directory name to append to name of file entry inside archive
128    * @param file the file to pack
129    * @throws IOException
130    */
131   private void packFile(ZipOutputStream zipFile, String dir, File file) throws IOException {
132     FileInputStream fileinputstream = new FileInputStream(file);
133     byte buf[] = new byte[fileinputstream.available()];
134     fileinputstream.read(buf);
135     String dirWithSlashes = dir.replace('\\', '/');
136     //System.out.println("zipping " + dirWithSlashes + "/" + file.getName());
137     ZipEntry ze = new ZipEntry(dirWithSlashes + "/" + file.getName());
138     ze.setMethod(ZipEntry.DEFLATED);
139     zipFile.putNextEntry(ze);
140     zipFile.write(buf, 0, buf.length);
141     zipFile.closeEntry();
142     fileinputstream.close();
143   }
144
145 }