2017-11-13 4 views
2

Ich habe eine Funktion, die eine Zip-Datei aus einer Liste von Dateien erstellt. Ist es möglich, die Zip-Datei zurückzugeben, ohne dass sie auf der Festplatte gespeichert wird? Ich brauche die Datei, da ich die Zip-Datei als Parameter für eine andere Funktion verwenden muss. Ich bin mir nicht sicher, ob der ByteStream eine Option für mich wäre.Zip-Datei aus ZipOutputStream in Java zurückgeben

public File compressFileList(List<File> fileList,String fileName) { 
    FileOutputStream fileOutputStream=null; 
    ZipOutputStream zipOutputStream=null; 
    FileInputStream fileInputStream=null; 
    String compressedFileName=fileName +".zip"; 
    if(fileList.isEmpty()) 
     return null; 
    try 
    { 
     fileOutputStream = new FileOutputStream(compressedFileName); 
     zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream)); 
     for (File file: fileList) { 
      fileInputStream = new FileInputStream(file); 
      ZipEntry zipEntry = new ZipEntry(file.getName()); 
      zipOutputStream.putNextEntry(zipEntry); 
      byte[] tmp = new byte[4*1024]; 
      int size = 0; 
      while((size = fileInputStream.read(tmp)) != -1){ 
       zipOutputStream.write(tmp, 0, size); 
      } 
      zipOutputStream.flush(); 
      fileInputStream.close(); 
     } 
     zipOutputStream.close(); 
     return compressedFile; //This is what I am missing 

    } 
    catch (FileNotFoundException e) 
    { 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

EDIT: Hinzufügen des Anwendungsfalles

Die Idee ist, eine Zip-Datei zu erstellen und die CreateClassifierOptions Methode des VisualRecognition Dienstes von Watson verwenden.

classifierOptions = new CreateClassifierOptions.Builder() 
      .classifierName("Santa") 
      .addClass("Santa", new File("C:\\app\\GitRepo\\images\\beagle.zip")) 
      .negativeExamples(new File("C:\\app\\GitRepo\\images\\nosport.zip")) 
      .build(); 

Der Builder übernimmt die Zip-Datei als Parameter.

Legendes

Auf der Grundlage der Erklärung von Alexandre Dupriez, ich denke, dass es besser ist, die Datei an einem Ort auf der Festplatte zu speichern.

+1

was macht die andere Funktion als Eingang akzeptieren? Ein 'Inputstream'? – Lino

+0

Ich verwende die WatsonService API, die eine Zip-Datei als Eingabe akzeptiert.oder vielleicht sollte ich eine temporäre ZIP-Datei erstellen und sie an die Funktion – Vini

+0

zurückgeben. Ihre Frage steht in Konflikt mit Ihrer Methodensignatur. Ein File-Objekt ist im Grunde ein Verweis auf eine Datei, die in einem Pfad gespeichert ist, aber Ihre Frage scheint darin zu bestehen, den (Byte-) Inhalt einer Datei zurückzugeben. Wenn Sie also Ihre Datei nicht irgendwo speichern möchten, sollten Sie kein File-Objekt zurückgeben. –

Antwort

3

sollten Sie in der Lage sein, einen verwenden ByteArrayOutputStream anstelle eine FileOutputStream:

zipOutputStream = new ZipOutputStream(new ByteArrayOutputStream()); 

Die Schwierigkeit dabei ist, ein File das Verfahren, um die Datei zip raubend. Die java.io.File bietet keine Abstraktion, mit der Sie In-Memory-Dateien bearbeiten können.

Die java.io.File Abstraktion und java.io.FileInputStream Implementierung

zu vereinfachen, wenn wir einkochen hatte, was die File Abstraktion ist, würden wir sehen es als eine URI. Um daher einen In-Memory-Speicher File aufzubauen oder ihn zumindest nachzuahmen, müssten wir einen URI bereitstellen, der dann vom Verbraucher der File dazu verwendet würde, seinen Inhalt zu lesen.

Wenn wir die FileInputStream aussehen, die die Verbraucher zu verwenden, ist wahrscheinlich, können wir sehen, dass es immer mit einem nativen Aufruf endet, die uns die Möglichkeit gibt überhaupt abstrahieren ein FileSystem für In-Memory-Dateien:

// class java.io.FileInputStream 
/** 
* Opens the specified file for reading. 
* @param name the name of the file 
*/ 
private native void open0(String name) throws FileNotFoundException; 

Es wäre einfacher, wenn es eine Möglichkeit gäbe, den Verbraucher anzupassen, um eine InputStream zu akzeptieren, aber aus Ihrer Problemstellung schätze ich, dass dies nicht möglich ist.

API-Aufruf

Ihre Anforderung ist ein File an der Watson von Visual API zur Verfügung zu stellen. Könnten Sie bitte die API-Methode angeben, die Sie anrufen müssen?

+0

Ich habe erwähnt, dass ich die obige Funktion eine Datei zurückgeben möchte. Die aufrufende Funktion akzeptiert nur eine Zip-Datei als Eingabe. – Vini

+0

Ja in der Tat - meinen Beitrag bearbeiten –

+0

Verwenden Sie dieses SDK: https://github.com/watson-developer-cloud/java-sdk? –

1
public void compressFileList(List<File> fileList, OutputStream outputStream) 
     throws IOException { 
    try (ZipOutputStream zipOutputStream = 
      new ZipOutputStream(new BufferedOutputStream(outputStream)); 
     for (File file: fileList) { 
      try (FileInputStream fileInputStream = new FileInputStream(file)) { 
       ZipEntry zipEntry = new ZipEntry(file.getName()); 
       zipOutputStream.putNextEntry(zipEntry); 
       byte[] tmp = new byte[4*1024]; 
       int size = 0; 
       while((size = fileInputStream.read(tmp)) != -1){ 
        zipOutputStream.write(tmp, 0, size); 
       } 
       zipOutputStream.flush(); 
      } catch (FileNotFoundException e) { // Maybe skip not found files. 
       Logger.log(Level.INFO, "File not found {}", file.getPath()); 
      } 
     } 
    } 
} 

Verbrauch:

if (fileList.isEmpty()) { 
    ... 
    return; 
} 
try { 
    compressFileList(fileList, servletRequest.getOutputStream())) { 
} catch (FileNotFoundException e) { 
    ... 
} catch (IOException e) { 
    ... 
} 
+0

Es gibt keine Datei zurück. Ich suche nach einer Option, um eine Zip-Datei zurückzugeben. Ich habe reallized, dass ich die Akte vorübergehend speichern muss, bevor ich es für die folgende Funktion verwenden könnte. – Vini

+0

Oder (wie in meiner Antwort) können Sie einen OutputStream für die Lieferung der ZIP-Datei übergeben. Dann müssen Sie kein Byte-Array mit dem Inhalt der Zip-Dateien verwalten. –

Verwandte Themen