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