Project

General

Profile

Download (3.58 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.io.common;
10

    
11
import java.io.File;
12
import java.io.FileOutputStream;
13
import java.io.IOException;
14
import java.io.OutputStream;
15
import java.util.HashMap;
16
import java.util.Map;
17
import java.util.zip.ZipEntry;
18
import java.util.zip.ZipOutputStream;
19

    
20
import org.apache.commons.io.output.DeferredFileOutputStream;
21

    
22
/**
23
 * Writing to zip files is not possible in parallel.
24
 * This class buffers streams into the zip file in
25
 * {@link DeferredFileOutputStream}s which store data in
26
 * memory or, if a certain threshold size is exceeded in
27
 * temporary files.
28
 * Calling {@link #close()} will write all data into the
29
 * given defined zip file.
30
 * Each entry offers its own {@link OutputStream} to write
31
 * into in parallel.
32
 *
33
 * @author a.mueller
34
 * @since 29.06.2017
35
 *
36
 */
37
public class ZipWriter {
38

    
39

    
40
    public static final int DEFAULT_THRESHOLD = 2000000;
41

    
42
    private int threshold = DEFAULT_THRESHOLD;
43

    
44
    private Map<String, DeferredFileOutputStream> entryMap  = new HashMap<>();
45

    
46
    private File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
47

    
48
    private File targetFile;
49

    
50
    /**
51
     * {@link ZipWriter} with default values.
52
     *
53
     * @param targetFile final zip file to be filled
54
     */
55

    
56
    public ZipWriter(File targetFile) {
57
        this(targetFile, null, null);
58
    }
59

    
60
    /**
61
     * @param targetFile final zip file to be filled
62
     * @param threshold the threshold when to start writing to file,
63
     *         uses default (2MB) if  <code>null</code>
64
     * @param tmpFolder the folder to write the temporary file to
65
     */
66
    public ZipWriter(File targetFile, Integer threshold, File tmpFolder) {
67
        super();
68
        this.targetFile = targetFile;
69
        this.threshold = threshold == null ? DEFAULT_THRESHOLD : threshold;
70
        this.tmpFolder = tmpFolder == null ? this.tmpFolder : tmpFolder;
71
    }
72

    
73

    
74

    
75
    public OutputStream getEntryStream(String entryName){
76
        DeferredFileOutputStream result = entryMap.get(entryName);
77
        if (result == null){
78
            result = new DeferredFileOutputStream(threshold, "tmp", "_zip_buffer", tmpFolder);
79
            entryMap.put(entryName, result);
80
        }
81
        return result;
82
    }
83

    
84
    public void close() throws IOException{
85
        FileOutputStream fos = new FileOutputStream(targetFile);
86
        ZipOutputStream zos = new ZipOutputStream(fos);
87
        for (String key:  entryMap.keySet()){
88
            ZipEntry zipEntry = new ZipEntry(key);
89
            zos.putNextEntry(zipEntry);
90
            DeferredFileOutputStream os = entryMap.get(key);
91
            os.close();
92
//            zos.setComment(comment);
93
            os.writeTo(zos);
94
            zos.closeEntry();
95
        }
96
        try {
97
            zos.finish();
98
            zos.close();
99
        } catch (IOException e) {
100
            throw e;
101
        }
102
        for (String key:  entryMap.keySet()){
103
            DeferredFileOutputStream os = entryMap.get(key);
104
            cleanupFile(os);
105
        }
106
    }
107

    
108
    private boolean cleanupFile(DeferredFileOutputStream os) {
109
        try {
110
            boolean deleted = true;
111
            File file = os.getFile();
112
            if (file != null){
113
                deleted = file.delete();
114
            }
115
            return deleted;
116
        } catch (Exception e) {
117
            //no matter, it should be in temp folder
118
            e.printStackTrace();
119
            return false;
120
        }
121
    }
122
}
(65-65/65)