Klassenbiliothek fuer Dateiverwaltung
e1fae256e29eb7a317d5a810d7e24751eb6032eb..1be785f6df00e3f36c00b58a2d0c623733c74621
9 hours ago ulrich
package-info auf den neuesten Stand gebracht
1be785 diff | tree
11 hours ago ulrich
Hinweis auf Gson in Readme hinzugefuegt
fd301d diff | tree
11 hours ago ulrich
Download-Link in Readme entfernt
f372ff diff | tree
11 hours ago ulrich
Download-Link in Readme berichtigt
4268ce diff | tree
11 hours ago ulrich
Buildinfos in Readme hinzugefuegt
0632aa diff | tree
11 hours ago ulrich
Readme hinzugefuegt
5c1183 diff | tree
11 hours ago ulrich
Hinweis auf Gson aufgenommen.
b659da diff | tree
11 hours ago ulrich
Ergaenzungen an Writer
93965f diff | tree
11 hours ago ulrich
Dokumentation in Arbeit: Writer fertig dokumentiert, kleinere Anpassungen
243c03 diff | tree
11 hours ago ulrich
Dokumentation in Arbeit: Mover fertig dokumentiert, kleinere Anpassungen
14367e diff | tree
12 hours ago ulrich
Dokumentation in Arbeit: Inflator fertig dokumentiert, kleinere Anpassungen
7e5166 diff | tree
12 hours ago ulrich
Dokumentation in Arbeit: ImageFileFilter fertig dokumentiert, kleinere Anpa...
6ea8d4 diff | tree
12 hours ago ulrich
Dokumentation in Arbeit: FileRef fertig dokumentiert, kleinere Anpassungen
02c8f8 diff | tree
12 hours ago ulrich
Dokumentation in Arbeit: kleinere Anpassungen
1b9e9c diff | tree
12 hours ago ulrich
Dokumentation in Arbeit: Eraser fertig dokumentiert, kleinere Anpassungen
b6536f diff | tree
13 hours ago ulrich
Dokumentation in Arbeit: Duplicator fertig dokumentiert, kleinere Anpassungen
ae26b0 diff | tree
13 hours ago ulrich
Dokumentation in Arbeit: DirList fertig dokumentiert, kleinere Anpassungen
ae2c69 diff | tree
13 hours ago ulrich
Dokumentation in Arbeit: Deflator fertig dokumentiert, kleinere Anpassungen
7c1911 diff | tree
13 hours ago ulrich
Dokumentation in Arbeit: Catalog fertig dokumentiert, kleinere Anpassungen
d618b8 diff | tree
13 hours ago ulrich
Dokumentation in Arbeit: Renamer fertig dokumentiert, kleinere Anpassungen
e8f9a4 diff | tree
14 hours ago ulrich
Dokumentation in Arbeit
8bde6f diff | tree
11 files modified
1 files added
2 files renamed
515 ■■■■ changed files
README.md 36 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Catalog.java 32 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Deflator.java 23 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/DirList.java 42 ●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Duplicator.java 17 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Eraser.java 22 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/FileHelper.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/fm/FileRef.java 69 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/ImageFileFilter.java 74 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Inflator.java 36 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Mover.java 32 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Renamer.java 37 ●●●● patch | view | raw | blame | history
src/de/uhilger/fm/Writer.java 27 ●●●●● patch | view | raw | blame | history
src/de/uhilger/fm/package-info.java 66 ●●●● patch | view | raw | blame | history
README.md
New file
@@ -0,0 +1,36 @@
# fm
Eine Klassenbibliothek zur Dateiverwaltung.
Weitere Informationen auf der [Produktseite](https://uhilger.de/data/pg/fm/)
## Voraussetzungen
Zur Herstellung von fm aus dem Quellcode wird ein Java Development Kit (JDK) benötigt. Das JDK ist von [Adoptium](https://adoptium.net/) frei erhältlich. In der hier folgenden weiteren Beschreibung wird der lokale Ablageort des Java Development Kits `$JDK` genannt.
## Quellcode von fm erhalten
Der Quellcode von fm wird von hier an einen frei wählbaren lokalen Ablageort heruntergeladen und entpackt. In der hier folgenden weiteren Beschreibung wird das so entstandene Verzeichnis `fm` einschließlich des absoluten Pfades dorthin `$FM` genannt. Anstelle von `$BASELINK` würde man also beispielweise `/home/fred/fm` notieren, wenn in das persönliche Verzeichnis des Benutzers `fred` heruntergealden und entpackt wurde.
## Klassenbibliothek herstellen
fm ist zur Nutzung im Zusammenspiel mit anderen Programmen vorgesehen und wird dazu am besten als Klassenbibliothek genutzt. Zur Herstellung einer Klassenbibliothek werden mit Hilfe der wie zuvor beschrieben geladenen Teile die folgenden Kommandos ausgeführt (Beispiel für Linux):
```
cd $FM
mkdir classes
mkdir dist
$JDK/bin/javac -d classes src/de/uhilger/fm/*.java
$JDK/bin/jar -cf dist/fm.jar -C classes .
```
Die fertig verwendbare Klassenbibliothek liegt anschließend unter `$FM/dist/fm.jar`.
## Klassenbibliothek verwenden
Zur Verwendung der Klassen von fm wird die Klassenbibliothek in den Classpath des Programmes aufgenommen, von dem aus fm genutzt werden soll. Neben fm wird zudem die Klassenbibliothek [Gson](https://google.github.io/gson/) benötigt.
## Lizenz
Veröffentlicht unter den Bedingungen der [GNU Affero General Public License](http://www.gnu.org/licenses/agpl-3.0)
src/de/uhilger/fm/Catalog.java
File was renamed from src/de/uhilger/fm/Lister.java
@@ -25,44 +25,48 @@
/**
 * Eine Klasse zur Bildung einer Liste mit den Dateien eines Verzeichnisses.
 * Eine Liste mit den Dateien eines Verzeichnisses bilden.
 * 
 * Varianten von Bilddateien werden ausgeblendet. Enthaelt ein Ordner die Dateien 
 *
 * <pre>
 * mein-bild.jpg
 * mein-bild_tn.jpg
 * mein-bild_kl.jpg
 * erscheint nur die Datei mein-bild.jpg in der Liste.
 * </pre>
 * 
 * erscheint nur die Datei mein-bild.jpg in der Liste.
 * 
 * @author Ulrich Hilger
 * @version 0.1, 05.11.2024
 */
public class Lister {
public class Catalog {
  public static final String STR_DOT = ".";
  private static final String STR_DOT = ".";
  /**
   * Eine Liste des Inhalts eines Ordners erstellen
   * 
   * @param fName Name und relativer Pfad des Ordners, dessen Inhalt aufgelistet werden soll
   * @param ctxPath  Kontext Pfad zur Bildung des URL, der auf die Miniaturansicht verweist
   * @param relPathAndName Name und relativer Pfad des Ordners, dessen Inhalt aufgelistet werden soll
   * @param urlBase  Kontext Pfad zur Bildung des URL fuer Miniaturansicht und imgsrc bei Bilddateien
   * (koennte evtl. im Client gebildet werden, hier dann nur Mini-Dateiname zurueckgeben)
   * @param base  Basisverzeichnis, gegen das der relative Pfad aufgeloest werden soll
   * @return die Dateiliste als JSON String
   * @throws IOException 
   */
  public String liste(String fName, String ctxPath, String base/*, String path*/) throws IOException {
    File[] files = new File(base, fName).listFiles(new ImageFileFilter());
  public String list(String relPathAndName, String urlBase, String base) throws IOException {
    File[] files = new File(base, relPathAndName).listFiles(new ImageFileFilter());
    if (files != null && files.length > 0) {
      Arrays.sort(files);
      ArrayList liste = new ArrayList();
      for (File file : files) {
        Datei datei = new Datei();
        FileRef datei = new FileRef();
        String dateiName = file.getName();
        datei.setName(dateiName);
        if (file.isDirectory()) {
          datei.setTyp(Datei.TYP_ORDNER);
          datei.setTyp(FileRef.TYP_ORDNER);
        } else {
          datei.setTyp(Datei.TYP_DATEI);
          datei.setTyp(FileRef.TYP_DATEI);
        }
        String lowerName = dateiName.toLowerCase();
        if (lowerName.endsWith(ImageFileFilter.JPEG)
@@ -71,7 +75,7 @@
          datei.setBild(true);
          String ext = dateiName.substring(dateiName.lastIndexOf(STR_DOT));
          String ohneExt = dateiName.substring(0, dateiName.lastIndexOf(STR_DOT));
          datei.setMiniurl(ctxPath + /*"/" + */ fName + ohneExt + ImageFileFilter.TN + ext);
          datei.setMiniurl(urlBase + /*"/" + */ relPathAndName + ohneExt + ImageFileFilter.TN + ext);
          //buildImgSrc(file, datei, ohneExt, ext);
        }
        liste.add(datei);
@@ -85,8 +89,8 @@
      //}
      if (!liste.isEmpty()) {
        DirList list = new DirList();
        list.setPfad(ctxPath + fName);
        list.setDateien(liste);
        list.setDirectory(urlBase + relPathAndName);
        list.setFiles(liste);
        Gson gson = new Gson();
        String json = gson.toJson(list);
        return json;
src/de/uhilger/fm/Deflator.java
@@ -27,33 +27,30 @@
import java.util.zip.ZipOutputStream;
/**
 * Eine Klasse mit Methoden zum Packen von Dateien #
 * Packen von Dateien
 *
 * @author Ulrich Hilger, 15. Januar 2024
 */
public class Deflator {
  
  private final String STR_SLASH = "/";
  /* --------------- 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
   * gepackt 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
   * @param fName Name und Pfad relativ zu base des zu packenden Ordners
   * @param base  absoluter Pfad zum Ablageort des zu packenden Ordners
   * @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(".")) {
  public String packFolder(String fName, /*String relPath, */String base) {
//    if (!relPath.startsWith(".")) {
      try {
        //String fName = getFileName(e);
        //logger.fine("fName: " + fName);
        if (fName.endsWith(STR_SLASH)) {
        if (fName.endsWith("/")) {
          File dir = new File(base, fName);
          if (dir.isDirectory()) {
            //logger.fine("absPath: " + dir.getAbsolutePath());
@@ -75,9 +72,9 @@
        //logger.log(Level.SEVERE, result, ex);
        return result;
      }
    } else {
      return "Falsche relative Pfadangabe";
    }
//    } else {
//      return "Falsche relative Pfadangabe";
//    }
  }
  /**
src/de/uhilger/fm/DirList.java
@@ -25,23 +25,47 @@
 * @author Ulrich Hilger, 15. Januar 2024
 */
public class DirList {
    private String pfad;
    private List<Datei> dateien;
    private String dir;
    private List<FileRef> dateien;
    public String getPfad() {
      return pfad;
    /**
     * Name und Pfad des Ordners ermitteln
     *
     * @return Name des Ordners
     */
    public String getDirectory() {
      return dir;
    }
    public void setPfad(String pfad) {
      this.pfad = pfad;
    /**
     * Name und Pfad des Ordners angeben
     *
     * @param path Name des Ordners
     */
    public void setDirectory(String path) {
      this.dir = path;
    }
    public List<Datei> getDateien() {
    /**
     * Die Liste mit Dateien und Ordnern ermitteln, die in
     * diesem Ordner enthalten sind
     *
     * @return Liste mit Dateien und Ordnern, die in
     * diesem Ordner enthalten sind
     */
    public List<FileRef> getFiles() {
      return dateien;
    }
    public void setDateien(List<Datei> dateien) {
      this.dateien = dateien;
    /**
     * Die Liste mit Dateien und Ordnern angeben, die in
     * diesem Ordner enthalten sind
     *
     * @param files Liste mit Dateien und Ordnern, die in
     * diesem Ordner enthalten sind
     */
    public void setFiles(List<FileRef> files) {
      this.dateien = files;
    }
    
  
src/de/uhilger/fm/Duplicator.java
@@ -22,12 +22,27 @@
import java.nio.file.Files;
/**
 *
 * Eine Datei duplizieren
 *
 * @author Ulrich Hilger
 * @version 0.1, 08.11.2024
 */
public class Duplicator {
  
  /**
   * Eine Datei duplizieren. Es entsteht eine neue Datei mit Namen
   * [Dateiname]-Kopie.[Endung], d.h. eine Datei namens datei.txt
   * wird dupliziert in datei-Kopie.txt
   *
   * Wenn die Zieldatei bereits existiert, wird der neuen Datei eine
   * laufende Nummer angehaengt, d.h. aus datei.txt wird datei-Kopie-1.txt,
   * wenn datei-Kopie.txt bereits existiert.
   *
   * @param base  der absolute Basispfad
   * @param relPfad relative Pfad nebst Name der zu duplizierenden Datei
   * @return  Name des erstellten Duplikats
   * @throws IOException  wenn etwas schief geht
   */
  public String duplizieren(String base, String relPfad) throws IOException {
    File srcFile = new File(base, relPfad);
    String fnameext = srcFile.getName();
src/de/uhilger/fm/Eraser.java
@@ -23,9 +23,11 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Eine Klasse mit Methoden zum Loeschen von Dateien
 * Loeschen von Dateien und Ordnern
 * 
 * @author Ulrich Hilger, 15. Januar 2024
 */
@@ -35,6 +37,15 @@
  
  private final String STR_DOT = ".";
  
  /**
   * Dateien und Ordner loeschen
   *
   * @param relPath  der relative Pfad, der gemeinsam mit 'base' den absoluten
   * Pfad zum Ordner ergibt, der die zu loeschenden Dateien enthaelt
   * @param fileNames  Liste mit Namen von Dateien und Ordnern, die geloescht werden sollen
   * @param base  absoluter Basispfad
   * @return "deleted" oder null, wenn ein Fehler auftrat
   */
  public String deleteFiles(String relPath, List<String> fileNames, String base) {
    String result = null;
    try {
@@ -68,11 +79,18 @@
        result = "deleted";
      }
    } catch (IOException ex) {
      //logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
      Logger.getLogger(Eraser.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
    }
    return result;
  }
  /**
   * Alle Varianten einer Bilddatei loeschen
   *
   * @param targetDir  der Ordner, aus dem geloescht werden soll
   * @param targetFile Bilddatei, deren Varianten geloescht werden sollen
   * @throws IOException wenn etwas schief geht
   */
  private void deleteImgFiles(File targetDir, File targetFile) throws IOException {
    String fnameext = targetFile.getName();
    int dotpos = fnameext.lastIndexOf(STR_DOT);
src/de/uhilger/fm/FileHelper.java
@@ -20,7 +20,7 @@
import java.io.File;
/**
 * FileHelper
 * Hilfsfunktionen fuer die Dateiverwaltung
 * 
 * @author Ulrich Hilger
 * @version 1, 04.07.2021
src/de/uhilger/fm/FileRef.java
File was renamed from src/de/uhilger/fm/Datei.java
@@ -18,12 +18,12 @@
package de.uhilger.fm;
/**
 * Datei-Referenz
 * Einfache Transportklasse fuer eine Datei-Referenz
 * 
 * @author Ulrich Hilger
 * @version 1, 11. Mai 2021
 */
public class Datei {
public class FileRef {
  
  public static final String TYP_DATEI = "datei";
  public static final String TYP_ORDNER = "ordner";
@@ -54,43 +54,96 @@
  private String miniurl;
  private String imgsrc;
  /**
   * Den Ausdruck fuer <code>imgsrc</code> ermitteln,
   * wenn es sich bei der Datei um eine Bilddatei handelt
   *
   * @return den imgsrc-Ausdruck
   */
  public String getImgSrc() {
    return imgsrc;
  }
  /**
   * Den Ausdruck fuer <code>imgsrc</code> angeben,
   * wenn es sich bei der Datei um eine Bilddatei handelt
   *
   * @param imgSrc  der imgsrc-Ausdruck
   */
  public void setImgSrc(String imgSrc) {
    this.imgsrc = imgSrc;
  }
  /**
   * Den URL der Miniaturansicht ermitteln,
   * wenn es sich bei der Datei um eine Bilddatei handelt
   *
   * @return URL der Miniaturansicht
   */
  public String getMiniurl() {
    return miniurl;
  }
  /**
   * Den URL der Miniaturansicht setzen,
   * wenn es sich bei der Datei um eine Bilddatei handelt
   *
   * @param miniurl URL der Miniaturansicht
   */
  public void setMiniurl(String miniurl) {
    this.miniurl = miniurl;
  }
  /**
   * Die CSS-Typ-Klasse fuer diese Datei ermitteln
   *
   * @return  die CSS-Typ-Klasse dieser Datei
   */
  public String getTypKlasse() {
    return typKlasse;
  }
  /**
   * Die CSS-Typ-Klasse fuer diese Datei setzen
   *
   * @param typKlasse die CSS-Typ-Klasse dieser Datei
   */
  public void setTypKlasse(String typKlasse) {
    this.typKlasse = typKlasse;
  }
  /**
   * Den Namen dieser Datei ermitteln
   *
   * @return Name dieser Datei
   */
  public String getName() {
    return name;
  }
  /**
   * Den Namen dieser Datei setzen
   *
   * @param name Name dieser Datei
   */
  public void setName(String name) {
    this.name = name;
  }
  /**
   * Den Typ dieser Datei ermitteln
   *
   * @return 'datei' oder 'ordner'
   */
  public String getTyp() {
    return typ;
  }
  /**
   * Den Typ dieser Datei setzen
   *
   * @param typ 'datei' oder 'ordner'
   */
  public void setTyp(String typ) {
    this.typ = typ;
    switch(typ) {
@@ -106,10 +159,20 @@
    }
  }
  /**
   * Ermitteln, ob es sich bei dieser Datei um ein Bild handelt
   *
   * @return true, wenn diese Datei ein Bild ist, false wenn nicht
   */
  public boolean isBild() {
    return bild;
  }
  /**
   * Den Bildindikator fuer diese Dateireferenz setzen
   *
   * @param istBild true, wenn diese Datei ein Bild ist, false wenn nicht
   */
  public void setBild(boolean istBild) {
    this.bild = istBild;
  }
src/de/uhilger/fm/ImageFileFilter.java
@@ -22,37 +22,53 @@
/**
 * Ein Filter zum Auslassen kleiner Versionen einer Original-Bilddatei
 *
 *
 * @author Ulrich Hilger
 * @version 1, 12. Mai 2021
 */
public class ImageFileFilter implements FileFilter {
  public static final String JPG = ".jpg";
  public static final String JPEG = ".jpeg";
  public static final String PNG = ".png";
  public static final String B64 = "_b64"; // Base64-Encoded
  public static final String TN = "_tn"; // 120
  public static final String KL = "_kl"; // 240
  public static final String SM = "_sm"; // 500
  public static final String MT = "_mt"; // 700
  public static final String GR = "_gr"; // 1200
    @Override
    public boolean accept(File pathname) {
      boolean pass = true;
      String fname = pathname.getName().toLowerCase();
      if(fname.endsWith(JPEG) ||
              fname.endsWith(JPG) || fname.endsWith(PNG)) {
        if(fname.contains(GR) || fname.contains(KL) ||
                fname.contains(MT) || fname.contains(SM) ||
                fname.contains(TN) || fname.contains(B64)) {
          pass = false;
        }
      }
      return pass;
    }
}
  /** Endung fuer JPEG-Bilddateien */
  public static final String JPG = ".jpg";
  /** Endung fuer JPEG-Bilddateien */
  public static final String JPEG = ".jpeg";
  /** Endung fuer PNG-Bilddateien */
  public static final String PNG = ".png";
  /** Namenszusatz fuer Base64-kodierte Dateien */
  public static final String B64 = "_b64"; // Base64-Encoded
  /** Namenszusatz fuer Bilddateien der Groesse 120 */
  public static final String TN = "_tn"; // 120
  /** Namenszusatz fuer Bilddateien der Groesse 240 */
  public static final String KL = "_kl"; // 240
  /** Namenszusatz fuer Bilddateien der Groesse 500 */
  public static final String SM = "_sm"; // 500
  /** Namenszusatz fuer Bilddateien der Groesse 700 */
  public static final String MT = "_mt"; // 700
  /** Namenszusatz fuer Bilddateien der Groesse 1200 */
  public static final String GR = "_gr"; // 1200
  /**
   * Bilddateien mit den Namenszusaetzen _tn, _kl, _sm, _mt, _gr und _b64 werden mit
   * diesem FileFilter weggelassen.
   *
   * @param pathname  Name und Pfad einer zu filternden Datei
   * @return false (weglassen), wenn pathname den Namenszusatz
   * _tn, _kl, _sm, _mt, _gr und _b64 enthaelt, sonst true
   */
  @Override
  public boolean accept(File pathname) {
    boolean pass = true;
    String fname = pathname.getName().toLowerCase();
    if (fname.endsWith(JPEG)
            || fname.endsWith(JPG) || fname.endsWith(PNG)) {
      if (fname.contains(GR) || fname.contains(KL)
              || fname.contains(MT) || fname.contains(SM)
              || fname.contains(TN) || fname.contains(B64)) {
        pass = false;
      }
    }
    return pass;
  }
}
src/de/uhilger/fm/Inflator.java
@@ -26,18 +26,23 @@
import java.util.zip.ZipFile;
/**
 * Eine Klasse mit Methoden zum entpacken von Dateien
 * Entpacken von Dateien
 *
 * @author Ulrich Hilger, 15. Januar 2024
 */
public class Inflator {
  /* --------- ZIP entpacken ---------------- */
  public String extractZipfile(String fName, String relPath, String base) {
  /**
   * Eine Zip-Datei entpacken
   *
   * @param fName Name der Zip-Datei
   * @param base absoluter Pfad des Ablageortes der Zip-Datei
   * @return 'ok', wenn erfolgreich oder Fehlermeldung, wenn nicht
   */
  public String extractZipfile(String fName, /*String relPath, */String base) {
    //logger.fine("fName: " + fName + ", relPath: " + relPath);
    String result = null;
    if (!relPath.startsWith(".")) {
//    if (!relPath.startsWith(".")) {
      try {
        //File targetDir = new File(fileBase, relPath);
        //File targetDir = getTargetDir(relPath);
@@ -51,17 +56,17 @@
        result = ex.getLocalizedMessage();
        //logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
      }
    } else {
      result = "Falsche relative Pfadangabe.";
    }
//    } else {
//      result = "Falsche relative Pfadangabe.";
//    }
    return result;
  }
  /**
   * extract a given ZIP archive to the folder respective archive resides in
   * Eine Datei in den Ordner entpacken, in dem sie liegt
   *
   * @param archive the archive to extract
   * @throws Exception
   * @param archive die zu entpackende Zip-Datei
   * @throws Exception wenn etwas schief geht
   */
  private boolean extract(File archive) throws Exception {
    ZipFile zipfile = new ZipFile(archive);
@@ -76,11 +81,12 @@
  /**
   * unzip a given entry of a given zip file to a given location
   * Einen Eintrag in einer ZIP-Datei an einen gegebenen Ausgabeort extrahieren
   *
   * @param zipfile the zip file to read an entry from
   * @param zipentry the zip entry to read
   * @param destPath the path to the destination location for the extracted content
   * @throws IOException
   * @param zipfile die Zip-Datei, aus der ein zu entpackender Eintrag gelesen werden soll
   * @param zipentry der Eintrag, der entpackt werden soll
   * @param destPath der Pfad zum Ausgabeort
   * @throws IOException wenn etwas schief geht
   */
  private void unzip(ZipFile zipfile, ZipEntry zipentry, String destPath) throws IOException {
    byte buf[] = new byte[1024];
src/de/uhilger/fm/Mover.java
@@ -24,7 +24,7 @@
import java.nio.file.Path;
/**
 * Die Klasse Mover verschiebt und kopiert Dateien und Ordner
 * Verschieben und Kopieren von Dateien und Ordnern
 * 
 * Handhabung von Bilddateien: 
 * 
@@ -40,6 +40,34 @@
  public static final int OP_MOVE = 2;
  
  /**
   * Dateien und Ordner kopieren
   *
   * @param fromPath der Pfad zur Quelle  der Kopieraktion
   * @param toPath der Pfad zum Ziel der Kopieraktion
   * @param fileNames die Liste der Dateien und Ordner, die kopiert werden sollen
   * @param base der Basispfad, gegen den fromPath und toPath aufgeloest werden sollen
   * @throws IOException wenn etwas schief geht
   */
  public void copy(String fromPath, String toPath, String[] fileNames, String base)
          throws IOException {
    copyOrMoveFiles(fromPath, toPath, fileNames, OP_COPY, base);
  }
  /**
   * Dateien und Ordner verschieben
   *
   * @param fromPath der Pfad zur Quelle  der Verschiebeaktion
   * @param toPath der Pfad zum Ziel der Verschiebeaktion
   * @param fileNames die Liste der Dateien und Ordner, die verschoben werden sollen
   * @param base der Basispfad, gegen den fromPath und toPath aufgeloest werden sollen
   * @throws IOException wenn etwas schief geht
   */
  public void move(String fromPath, String toPath, String[] fileNames, String base)
          throws IOException {
    copyOrMoveFiles(fromPath, toPath, fileNames, OP_MOVE, base);
  }
  /**
   * Dateien und Ordner verschieben oder kopieren
   * 
   * @param fromPath der Pfad zur Quelle  der Verschiebe- oder Kopieraktion
@@ -49,7 +77,7 @@
   * @param base der Basispfad, gegen den fromPath und toPath aufgeloest werden sollen
   * @throws IOException wenn etwas schief geht
   */
  public void copyOrMoveFiles(String fromPath, String toPath, String[] fileNames,
  private void copyOrMoveFiles(String fromPath, String toPath, String[] fileNames,
          int operation, String base) throws IOException {
    //String result = null;
    File srcDir = new File(base, fromPath);
src/de/uhilger/fm/Renamer.java
@@ -17,7 +17,6 @@
 */
package de.uhilger.fm;
import com.sun.net.httpserver.HttpExchange;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
@@ -25,7 +24,7 @@
import java.nio.file.Path;
/**
 * Eine Klasse mit Methoden zum Umbenennen von Dateien
 * Umbenennen von Dateien
 * 
 * @author Ulrich Hilger, 15. Januar 2024
 */
@@ -33,13 +32,21 @@
  
  public static final String STR_DOT = ".";
  
  public String umbenennen(/*HttpExchange exchange, */String relPfad, String neuerName, File file)
  /**
   * Eine Datei oder einen Ordner umbenennen
   *
   * @param neuerName  der Name fuer das Objekt
   * @param file  das Objekt, das umbenannt werden soll
   * @return der neue Name
   * @throws IOException wenn etwas schief geht
   */
  public String rename(/*HttpExchange exchange, *//*String relPfad,*/ String neuerName, File file)
          throws IOException {
    File neueDatei;
    String fname = file.getName().toLowerCase();
    if(fname.endsWith(ImageFileFilter.JPEG) || fname.endsWith(ImageFileFilter.JPG) || 
            fname.endsWith(ImageFileFilter.PNG)) {
      neueDatei = renameImgFiles(file.getParentFile(), file, neuerName);
      neueDatei = renameImgFiles(file, neuerName);
    } else {
      neueDatei = new File(file.getParentFile(), neuerName);
      file.renameTo(neueDatei);
@@ -47,17 +54,28 @@
    return neueDatei.getName();
  }
  
  public File renameImgFiles(File targetDir, File targetFile, String newName) throws IOException {
  /**
   * Alle Varianten einer Bilddatei umbenennen
   *
   * TODO einen sinnvolleren Rueckgabewert bauen
   *
   * @param file  die Origianlbilddatei
   * @param newName  der neue Name
   * @return  Name der letzten Datei, die umbenannt wurde
   * @throws IOException   wenn etwas schief geht
   */
  public File renameImgFiles(/*File targetDir, */ File file, String newName) throws IOException {
    String alt;
    String neu;
    File neueDatei = targetFile;
    File neueDatei = file;
    
    File targetDir = file.getParentFile();
    int newdotpos = newName.lastIndexOf(STR_DOT);
    String newfname = newName.substring(0, newdotpos);
    String newext = newName.substring(newdotpos);
    //logger.fine("newfname: " + newfname + ", newext: " + newext);
    
    String fnameext = targetFile.getName();
    String fnameext = file.getName();
    int dotpos = fnameext.lastIndexOf(STR_DOT);
    String fname = fnameext.substring(0, dotpos);
    String ext = fnameext.substring(dotpos);
@@ -87,7 +105,4 @@
    stream.close();
    return neueDatei;
  }
}
}
src/de/uhilger/fm/Writer.java
@@ -26,14 +26,19 @@
import java.util.logging.Logger;
/**
 * Dateien und Ordner anlegen.
 * Ggf. deren Inhalt schreiben.
 * Dateien und Ordner anlegen sowie gegebenenfalls den Inhalt von Dateien speichern.
 * 
 * @author Ulrich Hilger
 * @version 0.1, 07.11.2024
 */
public class Writer {
  /**
   * Einen Ordner anlegen, wenn er noch nicht exisitert
   *
   * @param file der Ordner, der angelegt werden soll
   * @return 0, wenn der Ordner angelegt wurde, -1 wenn nicht
   */
  public int newFolder(File file) {
    if (!file.exists()) {
      file.mkdir();
@@ -44,19 +49,21 @@
  }
  
  /**
   * Datei speichern. Eine existierende Datei gleichen Namens wird
   * zuvor geloescht (= Ueberschreiben).
   * Datei speichern.
   * 
   * Wenn Aenderungen in eine schon existierende Datei gespeichert werden
   * <p>Eine existierende Datei gleichen Namens wird
   * zuvor geloescht (= Ueberschreiben).</p>
   *
   * <p>Wenn Aenderungen in eine schon existierende Datei gespeichert werden
   * sollen, ist es noetig, die existierende Datei mit dem neuen Inhalt zu 
   * ueberschreiben, so, wie es diese Methode ausfuehrt.
   * ueberschreiben, so, wie es diese Methode ausfuehrt.</p>
   * 
   * Soll statdessen eine Datei neu erstellt werden und wird dabei also unterstellt, dass
   * <p>Soll statdessen eine Datei neu erstellt werden und wird dabei also unterstellt, dass
   * unter ihrem Namen am Ablageort noch keine Datei gleichen Namens existiert, muss 
   * vor der Verwendung dieser Methode sichergestellt werden, dass es so ist.
   * vor der Verwendung dieser Methode sichergestellt werden, dass es so ist.</p>
   * 
   * @param file
   * @param content
   * @param file die Datei, in die gespeichert werden soll
   * @param content  der zu speichernde Inhalt
   * @return 0, wenn erfolgreich, sonst -1
   */
  public int speichern(File file, String content) {
src/de/uhilger/fm/package-info.java
@@ -1,25 +1,23 @@
/**
 * Klassen fuer das Dateimanagement mit java.nio.file.
 * Klassen fuer das Dateimanagement mit <code>java.nio.file</code>.
 * 
 * Die folgenden Funktionen sind enthalten:
 * 
 * <pre>
 * Ordnerinhalt auflisten:    
 *    Lister().liste(ordnerName, ctx, basisOrdner)
 *
 *   TODO: JSON-Liste und Miniurl sowie Handhabung von Bilddateien ueberpruefen
 *    Catalog().list(relPathAndName, miniUrlBase, baseDir)
 * 
 * Datei speichern:
 *    Writer.speichern(file, content)
 *    Writer().speichern(file, content)
 * 
 * Dateien und Ordner loeschen:
 *    Eraser.deleteFiles(relPfad, dateiname, basis)
 *    Eraser().deleteFiles(relPfad, dateiname, basis)
 * 
 * Kopieren von Dateien und Ordnern:
 *    Mover().copyOrMoveFiles(quelle, ziel, dateiNamen, op, base)
 *    Mover().copy(quelle, ziel, dateiNamen, base)
 * 
 * Verschieben von Dateien und Ordnern:
 *    Mover().copyOrMoveFiles(quelle, ziel, dateiNamen, op, base)
 *    Mover().move(quelle, ziel, dateiNamen, base)
 * 
 * Duplizieren einer Datei:
 *    Duplicator().duplizieren(base, fileName)
@@ -33,5 +31,57 @@
 * Entpacken einer ZIP-Datei:
 *    Inflator().extractZipfile(fileName, path, base)
 * </pre>
 *
 * Die hier enthaltenen Funktionen beinhalten keine Massnahmen gegen Path Traversal o.&auml;.
 * Dies ist beabsichtigt, um Pfadausdruecke wie z.B. '../' bei den hier implementierten
 * Dateioperationen verarbeiten zu koennen.
 *
 * <p><b>Programme, die diese Klassenbibliothek einsetzen, muessen eigene Massnahmen gegen
 * Path Traversal o.&auml;. vorschalten, sofern dies nicht gewuenscht ist.</b></p>
 *
 * <p>Die folgenden Funktionalitaeten sind in dieser Auspraegung einer
 * Dateiverwaltung fest angelegt. Sie sind damit Kandidaten fuer eine
 * Erweiterung dieser Klassenbibliothek um andere evtl. benoetigte
 * Auspraegungen.</p>
 *
 * <p><b>Handhabung von Bilddateien</b></p>
 *
 * Neben der Datei eines Bildes in Originalgroesse werden weitere Dateien als Varianten
 * eines Bildes unterstuetzt.
 *
 * In Dateilisten werden diese Varianten ausgeblendet und nur das Originalbild gezeigt.
 *
 * Die Dateinamen von Varianten eines Bildes muessen dazu einen mit Unterstrich beginnenden
 * Namenszusatz enthalten wie bspw. <code>_tn</code> fuer thumbnail oder <code>_sm</code>
 * fuer small usw. Gleichsam lassen sich damit Eigenschaften wie zum Beispiel
 * eine Base64-Kodierung kombinieren. Hier waere der Namenszusatz dann eine Kombination
 * aus Groesse und Kodierung wie mit <code>_sm_b64</code>, so dass sich fuer ein Bild stets
 * eine ganze Gruppe von Dateien ergibt, z.B.:
 *
 * <pre>
 * bild.jpg
 * bild_sm.jpg
 * bild_sm_b64.jpg
 * </pre>
 *
 * Alle Dateioperationen dieser Klassenbibliothek wirken dennoch stets auf
 * alle Varianten des Bildes, wie es auf der Kommandozeile mit einem Wildcard-Operator
 * gemacht wuerde, z.B.
 *
 * <pre>
 *   cp /pfad/zum/bild*.jpg /pfad/zum/zielordner
 * </pre>
 *
 * Eine Dateiliste enthaelt aus diesem Grund fuer Bilddateien die beiden zusaetzlichen Angaben
 * <code>miniurl</code> und <code>imgsrc</code>.
 *
 * <p><b>Ordnerliste im JSON-Format</b></p>
 *
 * Die Liste mit Dateien eines Ordners wird im JSON-Format ausgegeben. Ueber eine
 * entsprechende Erweiterung koennte die Ausgabe in verschiedenen waehlbaren Formaten
 * erfolgen.
 *
 * Die Transformation nach JSON erfordert die Package <code>com.google.gson.Gson</code>.
 *
 */
package de.uhilger.fm;