Dateien verwalten mit Modul jdk.httpserver
ulrich
2024-01-22 c28d338cf5c917a867faf58204b85203d620f06e
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
144
145
146
/*
  http-cm - File management extensions to jdk.httpserver
  Copyright (C) 2021  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.httpserver.cm.actor;
 
import static de.uhilger.httpserver.cm.FileManager.STR_SLASH;
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 Zipper {
 
  /* --------------- 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(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();
    }
 
      
}