Use-Case:
Also ich hab viele Dateien quer über das aktive Windows-System verteilt, die ich gerne sichern möchte. Zip-Datei.
Usage:
Zuerst muss eine Datei „dirs1.txt“ erstellt werden, in der in jeder Zeile der vollständige Pfad zu einem zu sichernden Verzeichnis steht.
Danach kann man das Programm starten. Wenn ein Verzeichnis mehr als 1000 Dateien oder mehr als 1GB enthält, wird man gefragt, ob man dieses Verzeichnis von der Sicherung ausschließen möchte oder nicht.
Danach wird eine Datei „ex1.txt“ erstellt, mit den auszuschließenden Dateien, diese werden beim nächsten Programmstart wiederverwendet, insofern die Datei nicht gelöscht wird.
Danach erstellt das Programm die Sicherung, schließt dabei aber die Verzeichnisse und Dateien von „ex1.txt“ aus, sowie Dateien, die versteckt sind oder nicht gelesen werden können.
Code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import javax.swing.JOptionPane;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ExcludeFileFilter;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
public class BackupTool {
private static final String backup_password = "pw";
private static final long max_count = 1000;
private static final long max_size = 1000 * 1000 * 1000;
private static final File backup_file;
static {
SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateTimeInstance();
sdf.applyPattern("yyyy-MM-dd-HH-mm-ss");
backup_file = new File("backup1-" + sdf.format(new Date()) + ".zip");
}
public static void folderSize(File directory, long[] countAndSize) {
File[] files = directory.listFiles();
if (files == null || files.length == 0) {
return;
}
countAndSize[0] += files.length;
if (countAndSize[0] > max_count) {
return;
}
for (File file : files) {
if (file.isFile()) {
countAndSize[1] += file.length();
if (countAndSize[1] > max_size) {
return;
}
} else {
folderSize(file, countAndSize);
}
}
}
public static ArrayList<File> readDirs1() throws IOException {
ArrayList<File> dirs1 = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("dirs1.txt"))) {
String l;
while ((l = br.readLine()) != null) {
dirs1.add(new File(l));
}
}
return dirs1;
}
public static HashSet<File> readEx1() throws IOException {
HashSet<File> ex1 = new HashSet<>();
if (new File("ex1.txt").exists()) {
try (BufferedReader br = new BufferedReader(new FileReader("ex1.txt"))) {
String l;
while ((l = br.readLine()) != null) {
ex1.add(new File(l));
}
}
return ex1;
}
return null;
}
public static ArrayList<File> createEx2(ArrayList<File> dirs1) throws IOException {
ArrayList<File> ex1 = new ArrayList<>();
for (File file : dirs1) {
Files.walkFileTree(file.toPath(), new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
File f = dir.toFile();
if (f.isHidden()) {
return FileVisitResult.SKIP_SUBTREE;
}
if (!f.canRead()) {
return FileVisitResult.SKIP_SUBTREE;
}
long[] cas = new long[2];
folderSize(f, cas);
if (cas[0] > max_count || cas[1] > max_size) {
if (JOptionPane.showConfirmDialog(null,
"Exclude: " + f.toString() + " ?") == JOptionPane.YES_OPTION) {
ex1.add(f);
return FileVisitResult.SKIP_SUBTREE;
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
return ex1;
}
public static void storeEx2(ArrayList<File> ex2) throws IOException {
for (File file : ex2) {
System.out.println(file);
}
try (PrintWriter pw = new PrintWriter("ex1.txt")) {
for (File file : ex2) {
pw.println(file.toString());
}
}
}
public static void createZip(ArrayList<File> dirs1, HashSet<File> ex1) throws ZipException {
ZipParameters p = new ZipParameters();
p.setExcludeFileFilter(new ExcludeFileFilter() {
@Override
public boolean isExcluded(File file) {
return ex1.contains(file) || file.isHidden() || !file.canRead();
}
});
p.setEncryptFiles(true);
p.setEncryptionMethod(EncryptionMethod.AES);
// Below line is optional. AES 256 is used by default. You can override it to
// use AES 128. AES 192 is supported only for extracting.
p.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
ZipFile zipFile = new ZipFile(backup_file, backup_password.toCharArray());
for (File file : dirs1) {
zipFile.addFolder(file, p);
}
System.out.println("fertig");
}
public static void main(String[] args) throws IOException {
ArrayList<File> dirs1 = readDirs1();
HashSet<File> ex1 = readEx1();
if (ex1 == null) {
ArrayList<File> ex2 = createEx2(dirs1);
storeEx2(ex2);
ex1 = new HashSet<>(ex2);
}
ex1.add(backup_file);
createZip(dirs1, ex1);
}
}
Maven:
<!-- https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j -->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.6.2</version>
</dependency>
github: https://github.com/srikanth-lingala/zip4j
Troubleshooting: Die Dateien werden mit einem Passwort gesicht, allerdings ist das komplette Zip nicht mit einem Passwort gesichert… also man kann die Dateien sehen, ohne das Passwort zu kennen.