ich behandle in meinen Einsteigeruebungen gerade Datenstreams, wozu natürlich auch einfache Komprimierung zählt.
Das folgende Programm soll eine Liste von Dateipfaden übergeben bekommen und diese dann mit Gzip komprimieren.
import java.io.*;
import java.util.zip.GZIPOutputStream;
import java.util.Scanner;
//Erzeugung mit Gzip komprimierter Dateien
public class Gzip {
static public void main(String[] args) {
String[] list = new String[10];
int i = 0;
while(i<10) {
if(SetFileNames().equals("EXIT")) break;
list** = SetFileNames();
}
pack(list);
}
static String SetFileNames() {
System.out.print("Datei- oder Verzeichnispfad eingeben: ");
Scanner nameInp = new Scanner(System.in);
String name = nameInp.nextLine();
return name;
}
static public void pack(String[] argDat) {
int gelesen = 0;
byte[] buff = new byte[2048];
for(int i = 0; i < argDat.length; i++) {
try {
File datei = new File(argDat**);//Fehler: argDat**=null???
if(datei.exists() && datei.isFile()) {
FileInputStream in = new FileInputStream(datei);
FileOutputStream out = new FileOutputStream(argDat** + ".gz");
GZIPOutputStream gzipout = new GZIPOutputStream(out);
while((gelesen=in.read(buff, 0, 2048)) != -1) {
gzipout.write(buff, 0, gelesen);
}
in.close();
gzipout.close();
datei.delete();
} else {
System.out.println(argDat** + " ist keine gueltige Datei.");
}
} catch(Exception e) {
System.out.println("Fehler!");
e.printStackTrace();
}
}
}
}
Der Compiler beschwert sich nicht.
An der angemerkten Stelle bekomme ich allerdings sobald pack(list) aufgerufen wird eine NullPointerException, da argDat** anscheinend auf nichts zeigt. Ich verstehe nicht ganz warum das hier so ist. Habe schon mehrere Dinge ausprobiert, etwa list[] durch eine eigene statische Methode zu erzeugen, hat aber nichts verändert.
Was muss ich verändern, damit argDat** den richtigen Wert hat?
Sry falls das Programm an sich zu viel Code für den beschriebenen Zweck enthalten sollte, bin ein absoluter Anfänger.
Vielen Dank für jede Hilfe!
was ist denn deine Eingabe zum Programm, gibst du 20 (!) Werte ein oder früher break; ?
bei der EXIT-Abfrage jede Runde wird ja auch ein kompletter Name abgefragt, wenn nicht EXIT dann dieser Wert verworfen,
vielleicht lieber ändern:
nur einen String abfragen, wenn EXIT dann break, sonst diesen Wert in Array speichern
ganz wichtig ist bei sowas, System.out.println() zu benutzen,
nach list** = SetFileNames(); gehört eine Ausgabe dass an Position i nun Wert soundso steht,
damit du mitkommst,
später das komplette Array ausgeben (API Arrays.toString(array) nutzen oder Schleife), um zu wissen ob null drinsteckt,
in der Verarbeitungsschleife vor der File-Erstellung ruhig auch wieder Ausgabe, kommt freilich auf das Gleiche hinaus
i in main wird nicht hochgezählt, wenn du einmal mehr als 10 Werte eingibst, bekommst du eine ArrayOutOfBoundsException
natürlich kann in Zeile 29 der Wert im Arrays null sein. Was erwartest du denn für einen Wert, wenn du fünf eingegeben hast, und in deiner Schleife den sechsten ausliest? Also entweder musst du dir in einer extra-Variablen merken, wieviel Werte übergeben wurden, oder du musst auf null-Werte testen (und dann gar nichts tun) oder du musst eine geeignete Datenstruktur statt des Arrays verwenden (ich habe schon einige gute Dinge über Listen gehört)
Dies ist ein gutes Beispiel warum man Schleifen nicht mit break verlassen sollte. In diesem Fall verschleiert es nämlich, dass die Abbruchbedingung Deiner Schleife (also das was hinter while in der Klammer steht) nie zutrifft.
Zum Andern zeigt Dein Beispiel auch, warum man lieber mit [JAPI]Collection[/JAPI]-Objekten statt mit Arrays arbeiten sollte, denn static public void main(String[] args) { Collection<String> list = new HashSet<>(); int i = 0; while(!SetFileNames().equals("EXIT")) list.add( SetFileNames()); } pack(list); }hätte das Problem mit der unerwarteten NULL-Referenz in nicht verwendeten Array-Elementen einfach nicht.[SPOILER]Warum Du damit nur jede zweite Datei erwischst überlasse ich mal Deiner Intelligenz…[/SPOILER]
Also, erstmal danke für die zahlreiche Hilfe, hab ich mich zugegebenermaßen ein bisschen blöd angestellt.
So funktioniert der Code wie er soll:
import java.io.*;
import java.util.Arrays;
import java.util.zip.GZIPOutputStream;
import java.util.Scanner;
//Erzeugung mit Gzip komprimierter Dateien
public class Gzip {
static public void main(String[] args) {
String[] list = new String[10];
//Speicherung von max 10 Dateipfaden in einem String-Array
for(int i = 0; i<10; i++) {
System.out.print("Dateipfad eingeben: ");
Scanner nameInp = new Scanner(System.in);
String name = nameInp.nextLine();
if(name.equals("EXIT")) {
break;
}
else {
list** = name;
}
System.out.println(list**);
System.out.println(Arrays.toString(list));
}
pack(list);
}
static public void pack(String[] argDat) {
int gelesen = 0;
byte[] buff = new byte[2048];
for(int i = 0; i < argDat.length; i++) {
try {
if(argDat**==null) {
break;
}
else {
File datei = new File(argDat**);//Fehler: argDat**==null???
if(datei.exists() && datei.isFile()) {
FileInputStream in = new FileInputStream(datei);
FileOutputStream out = new FileOutputStream(argDat** + ".gz");
GZIPOutputStream gzipout = new GZIPOutputStream(out);
while((gelesen=in.read(buff, 0, 2048)) != -1) {
gzipout.write(buff, 0, gelesen);
}
in.close();
gzipout.close();
datei.delete();
} else {
System.out.println(argDat** + " ist keine gueltige Datei.");
}
}
} catch(Exception e) {
System.out.println("Fehler!");
e.printStackTrace();
}
}
}
}
Eigentlich sollte man sich ja die ganze Eingabesache, also hier die main Methode sparen und in die Kommandozeile einfach “java Gzip blabla.txt” eingeben können oder?
Kommt bei mir allerdings immer die Meldung, die Hauptklasse sei nicht gefunden worden. Habt ihr ne Idee, was da helfen würde? (Solange blame ich einfach mal Windows)
Schönen Abend noch
bei Kommandozeile sind Dinge zu beachten, vom richtigen Verzeichnis aus aufzurufen, alle benötigten zusätzlichen Daten korrekt angegeben (ClassPath), das ist für sich einfach eine Aufgabe,
Vorhandensein von IDE hat normalerweise damit nichts zu tun,
freilich sind IDE-Projekte für sich auf eine bestimmte Weise aufgebaut, die man beachten müsste,
.class-Dateien etwa nicht bei den .java-Dateien, nur .class-Dateien zur Ausführung wichtig,
die IDE selber passt schon zu allem gut auf, dass die funktioniert ist kein positives oder negatives Anzeichen Richtung Konsole