Problem beim Speichern von ZIP Files über HTTP

zer0

Erfahrenes Mitglied
Hallo,

ich lade per Java Dateien runter. Bei normalen .csv Dateien ist das kein Problem, dort habe ich bis jetzt immer den FileWriter benutzt. Nur ist mir jetzt aufgefallen das die .zip Dateien Probleme machen. Die Datei wird zwar erstellt, beim öffnen kommt jedoch dieser Fehler:

C:\data\RoughData.zip: Unerwartetes Archivende.

Ich nehm mal an das liegt daran das Zip-Dateien nun mal keine Zeichenketten sind, wie zum Beispiel CSV-Dateien.

Ich habe folgenden HTTP Header:
HTTP/1.1 200 OK
Server: Sun-Java-System-Web-Server/7.0
Date: Wed, 12 Oct 2011 11:59:55 GMT
Content-type: application/octet-stream
Content-Disposition: attachment; filename=RoughData.zip
Cache-Control: max-age=0
Transfer-encoding: chunked
Connection: Keep-Alive

Jetzt weiß ich das der Inhalt des HTTP Response die Zip-Datei ist, wie behandel ich das nun? Kann ich das ganze in ein String umwandeln und erst beim schreiben in die Datei darauf achten ein besonderen Writer zu nehmen? Wie schreibe ich Zip-Dateien?
 
Hi,

also den Typ der Datei erkennst du (normalerweiße) an der Endung. Demnach musst du bei deinem HTTP Header den 'filenamen=...' rausfiltern und die FileExtension ermitteln.
Ist die Datei eine Zip-Datei, schreibst du diese über den ZipOutputStream.

Gruß

Fabio
 
Hi.

Das Ganze hat überhaupt nichts mit dem Dateityp zu tun. Mal abgesehen davon, das man den Typ einer Datei besser am MIME Type erkennt, als an der Endung.

Der FileWriter ist dafür ungeeignet, verwende einfach einen FileOutputStream.

Gruß
 
FileWriter ist wie alle Writer und Reader Klassen NUR für Strings/darstellbare Zeichen geeignet. Ein ZIP ist jedoch eine Binärdatei ... hier brauchst du eine von InputStream/OutputStream abgeleitete Klasse ... auch für das lesen vom Server ... wenn du hier schon mit einem Reader arbeitest , also darauf vertraust das nur darstellbare Zeichen kommen ist das schon der falsche Ansatz.
Benutz mal unsere SuFu ... da solltest du einen HTTP-Downloader finden. Alternativ kannst du dich auch mal mit der Apache-Commons-Lib auseinandersetzen *Hilfe dazu sollten dir hier einige geben können*.

Wenn du von einem HTTP-Server laden willst kannst du auch mit URL.openConnection() arbeiten und mit instanceof auf HttpURLConnection prüfen. Die nimmt dir einiges ab was HTTP angeht.
 
Hi.

Das Ganze hat überhaupt nichts mit dem Dateityp zu tun. Mal abgesehen davon, das man den Typ einer Datei besser am MIME Type erkennt, als an der Endung.

Der FileWriter ist dafür ungeeignet, verwende einfach einen FileOutputStream.

Gruß

Ich habe jetzt folgende Lösung die sowohl für CSV als auch ZIP Dateien funktioniert:
Java:
    public void saveContent(String fileName, String content) throws HttpCommunicationException {
        if (fileName == null) {
            throw new NullPointerException("fileName is null!");
        }

        Writer writer = null;

        try {
            File file = new File(getDirectory(), fileName);
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "ISO-8859-1"));
            writer.write(content);

            System.out.println(content.getBytes().length + " Bytes geschrieben in " + file.getAbsolutePath());
        } catch (FileNotFoundException ex) {
            throw new HttpCommunicationException(ex);
        } catch (IOException ex) {
            throw new HttpCommunicationException(ex);
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException ex) {
                throw new HttpCommunicationException(ex);
            }
        }
    }

Stellt es ein Problem dar, wenn ich den FileOutputStream auch für Stringbasierte-Formate benutze? Sollte ich zwischen sollen Formaten unterscheiden beim Schreiben?
 
Hi.

Warum hast du den Inhalt denn jetzt als String? Warum verwendest du nicht ein byte Array?

Warum kodierst du das als iso-8859-1? Vermutlich hast du vorher die Daten von der Webseite gelesen, als iso-8859-1 interpretieren lassen und in einen String (welcher UTF-16 ist) gespeichert. Das ist nicht gerade sinnvoll, oder?!
Stellt es ein Problem dar, wenn ich den FileOutputStream auch für Stringbasierte-Formate benutze? Sollte ich zwischen sollen Formaten unterscheiden beim Schreiben?
Wenn du von einer URL Daten 1:1 in eine Datei schreiben willst, solltest du überhaupt keine Strings verwenden.

Wenn es sich dabei um text/* handelt, kannst du den Inhalt in einen String konvertieren.

Gruß
 
Hallo,

ich arbeite mit dem Apache HTTP Client. Dort gebe ich einen Response Handler an, der den Response erhält und verarbeitet. Dieser Response Handler ist generisch, ich erbe von ihm setzte den Rückgabetyp entweder zu String, wie bisher oder etwas anderem.

Denkst du der Rückgabetyp byte[] wäre sinvoller? Ich müsste dann halt auch Textdateien damit schreiben!
 
ich arbeite mit dem Apache HTTP Client. Dort gebe ich einen Response Handler an, der den Response erhält und verarbeitet. Dieser Response Handler ist generisch, ich erbe von ihm setzte den Rückgabetyp entweder zu String, wie bisher oder etwas anderem.

Denkst du der Rückgabetyp byte[] wäre sinvoller?
Allerdings. Wenn du da irgendwas als String interpretierst, mußt du dich auf ein bestimmtes Encoding festlegen. Das führt im ungünstigen Fall zu Fehlern.
Ich müsste dann halt auch Textdateien damit schreiben!
Es ist völlig egal was für Dateien das sind.

getResponseBody()

oder

getResponseBodyAsStream()

Gruß
 
Das wäre in der Tat am sinvollsten, da muss ich deepthroat recht geben.
Das byte[] kannst du dann über die writer.write(byte[], 0, byte[].length) schreiben.
 
Hallo,

ich arbeite mit dem HTTP Client, dort gibt es die Methoden getResponseBody etc. nicht!

Muss ich den mit Fehlern rechnen wenn ich den Inhalt als String "zwischenspeicher"? Selbst wenn ich ihn beim Schreiben zuerst in ein Byte-Array umwandle, undzwar mit dem selben Charset wie beim erstellen des Strings?

Mein Problem ist das ich im Reponse Handler die Daten verarbeite, und manchmal auch untersuche. Denn die Daten sind ja auch HTML Text, wo ich dann nach bestimmten Informationen suche. Das ist in einem Byte-Array nich so einfach möglich :p
 
Zurück