blob: 3a5084a08623a5a4ca13054684fbc5d53f0e4166 [file] [log] [blame]
Torsten Curdtca165392008-07-10 10:17:44 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.commons.compress.archivers;
20
Sebastian Bazleyfec51a12009-03-31 00:35:56 +000021import java.io.File;
Torsten Curdtca165392008-07-10 10:17:44 +000022import java.io.IOException;
23import java.io.OutputStream;
24
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000025/**
26 * Archive output stream implementations are expected to override the
27 * {@link #write(byte[], int, int)} method to improve performance.
28 * They should also override {@link #close()} to ensure that any necessary
29 * trailers are added.
Christian Grobmeier6dfdfb52009-04-22 05:19:58 +000030 *
Stefan Bodewigd244dc62013-04-25 15:25:04 +000031 * <p>The normal sequence of calls when working with ArchiveOutputStreams is:</p>
32 * <ul>
33 * <li>Create ArchiveOutputStream object,</li>
34 * <li>optionally write SFX header (Zip only),</li>
35 * <li>repeat as needed:
36 * <ul>
37 * <li>{@link #putArchiveEntry(ArchiveEntry)} (writes entry header),
38 * <li>{@link #write(byte[])} (writes entry data, as often as needed),
39 * <li>{@link #closeArchiveEntry()} (closes entry),
40 * </ul>
41 * </li>
42 * <li> {@link #finish()} (ends the addition of entries),</li>
43 * <li> optionally write additional data, provided format supports it,</li>
44 * <li>{@link #close()}.</li>
45 * </ul>
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000046 */
Stefan Bodewigc30b5882009-02-10 15:35:35 +000047public abstract class ArchiveOutputStream extends OutputStream {
Sebastian Bazley39c93f42012-03-31 12:30:09 +000048
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000049 /** Temporary buffer used for the {@link #write(int)} method */
50 private final byte[] oneByte = new byte[1];
51 static final int BYTE_MASK = 0xFF;
Stefan Bodewigf77e1f12009-02-06 17:24:01 +000052
Stefan Bodewig2dca6612010-02-18 16:10:20 +000053 /** holds the number of bytes written to this stream */
54 private long bytesWritten = 0;
Sebastian Bazleycf003d12009-03-30 20:35:08 +000055 // Methods specific to ArchiveOutputStream
Sebastian Bazley39c93f42012-03-31 12:30:09 +000056
Sebastian Bazleycf003d12009-03-30 20:35:08 +000057 /**
58 * Writes the headers for an archive entry to the output stream.
59 * The caller must then write the content to the stream and call
60 * {@link #closeArchiveEntry()} to complete the process.
61 *
62 * @param entry describes the entry
63 * @throws IOException
64 */
Stefan Bodewigf77e1f12009-02-06 17:24:01 +000065 public abstract void putArchiveEntry(ArchiveEntry entry) throws IOException;
Stefan Bodewig3f9bcc62009-02-10 14:20:05 +000066
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000067 /**
68 * Closes the archive entry, writing any trailer information that may
69 * be required.
70 * @throws IOException
71 */
Torsten Curdtca165392008-07-10 10:17:44 +000072 public abstract void closeArchiveEntry() throws IOException;
Sebastian Bazley39c93f42012-03-31 12:30:09 +000073
Christian Grobmeier6dfdfb52009-04-22 05:19:58 +000074 /**
75 * Finishes the addition of entries to this stream, without closing it.
76 * Additional data can be written, if the format supports it.
Christian Grobmeierd170f342009-04-22 06:05:23 +000077 *
Stefan Bodewigd244dc62013-04-25 15:25:04 +000078 * @throws IOException if the user forgets to close the entry.
Christian Grobmeier6dfdfb52009-04-22 05:19:58 +000079 */
80 public abstract void finish() throws IOException;
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000081
Sebastian Bazleyfec51a12009-03-31 00:35:56 +000082 /**
83 * Create an archive entry using the inputFile and entryName provided.
84 *
85 * @param inputFile
86 * @param entryName
87 * @return the ArchiveEntry set up with details from the file
88 *
89 * @throws IOException
90 */
91 public abstract ArchiveEntry createArchiveEntry(File inputFile, String entryName) throws IOException;
Sebastian Bazley39c93f42012-03-31 12:30:09 +000092
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000093 // Generic implementations of OutputStream methods that may be useful to sub-classes
Sebastian Bazley39c93f42012-03-31 12:30:09 +000094
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000095 /**
96 * Writes a byte to the current archive entry.
97 *
Stefan Bodewigd244dc62013-04-25 15:25:04 +000098 * <p>This method simply calls {@code write( byte[], 0, 1 )}.
Sebastian Bazley52fcfa02009-03-30 17:17:58 +000099 *
Stefan Bodewigd244dc62013-04-25 15:25:04 +0000100 * <p>MUST be overridden if the {@link #write(byte[], int, int)} method
Sebastian Bazley52fcfa02009-03-30 17:17:58 +0000101 * is not overridden; may be overridden otherwise.
102 *
103 * @param b The byte to be written.
104 * @throws IOException on error
105 */
Sebastian Bazleyfb06e3a2011-08-15 15:10:46 +0000106 @Override
Sebastian Bazley52fcfa02009-03-30 17:17:58 +0000107 public void write(int b) throws IOException {
108 oneByte[0] = (byte) (b & BYTE_MASK);
109 write(oneByte, 0, 1);
110 }
111
Christian Grobmeierab269432009-04-24 06:30:17 +0000112 /**
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000113 * Increments the counter of already written bytes.
Stefan Bodewigd244dc62013-04-25 15:25:04 +0000114 * Doesn't increment if EOF has been hit ({@code written == -1}).
Christian Grobmeierab269432009-04-24 06:30:17 +0000115 *
Stefan Bodewigb0d75e62010-02-18 16:30:37 +0000116 * @param written the number of bytes written
Christian Grobmeierab269432009-04-24 06:30:17 +0000117 */
Stefan Bodewig58568f42010-02-18 16:24:31 +0000118 protected void count(int written) {
119 count((long) written);
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000120 }
121
122 /**
123 * Increments the counter of already written bytes.
Stefan Bodewigd244dc62013-04-25 15:25:04 +0000124 * Doesn't increment if EOF has been hit ({@code written == -1}).
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000125 *
126 * @param written the number of bytes written
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000127 * @since 1.1
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000128 */
129 protected void count(long written) {
130 if (written != -1) {
131 bytesWritten = bytesWritten + written;
Christian Grobmeierab269432009-04-24 06:30:17 +0000132 }
133 }
Sebastian Bazley39c93f42012-03-31 12:30:09 +0000134
Christian Grobmeierab269432009-04-24 06:30:17 +0000135 /**
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000136 * Returns the current number of bytes written to this stream.
137 * @return the number of written bytes
138 * @deprecated this method may yield wrong results for large
139 * archives, use #getBytesWritten instead
Christian Grobmeierab269432009-04-24 06:30:17 +0000140 */
Stefan Bodewig4a825302011-08-06 13:20:22 +0000141 @Deprecated
Christian Grobmeierab269432009-04-24 06:30:17 +0000142 public int getCount() {
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000143 return (int) bytesWritten;
144 }
145
146 /**
147 * Returns the current number of bytes written to this stream.
148 * @return the number of written bytes
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000149 * @since 1.1
Stefan Bodewig2dca6612010-02-18 16:10:20 +0000150 */
151 public long getBytesWritten() {
152 return bytesWritten;
Christian Grobmeierab269432009-04-24 06:30:17 +0000153 }
Stefan Bodewiga33505b2010-02-19 12:23:27 +0000154
155 /**
156 * Whether this stream is able to write the given entry.
157 *
158 * <p>Some archive formats support variants or details that are
159 * not supported (yet).</p>
160 *
Gary D. Gregory6311a902013-12-20 17:41:43 +0000161 * @param archiveEntry
162 * the entry to test
163 * @return This implementation always returns true.
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000164 * @since 1.1
Stefan Bodewiga33505b2010-02-19 12:23:27 +0000165 */
Gary D. Gregory6311a902013-12-20 17:41:43 +0000166 public boolean canWriteEntryData(ArchiveEntry archiveEntry) {
Stefan Bodewiga33505b2010-02-19 12:23:27 +0000167 return true;
168 }
Torsten Curdtca165392008-07-10 10:17:44 +0000169}