1 /*******************************************************************************
2 * Copyright (c) 2004, 2015 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 * Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 243347 TarFile should not throw NPE in finalize()
11 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Bug 463633
12 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Copied to Trace Compass to work around bug 501379
13 *******************************************************************************/
15 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.wizards
.importtrace
;
18 import java
.io
.FileInputStream
;
19 import java
.io
.IOException
;
20 import java
.io
.InputStream
;
21 import java
.util
.Enumeration
;
23 import org
.apache
.commons
.compress
.archivers
.tar
.TarArchiveEntry
;
24 import org
.apache
.commons
.compress
.archivers
.tar
.TarArchiveInputStream
;
25 import org
.apache
.commons
.compress
.compressors
.gzip
.GzipCompressorInputStream
;
29 * Reads a .tar or .tar.gz archive file, providing an index enumeration
30 * and allows for accessing an InputStream for arbitrary files in the
33 public class TarFile
{
35 private TarArchiveInputStream entryEnumerationStream
;
36 private TarArchiveEntry curEntry
;
37 private TarArchiveInputStream entryStream
;
39 private InputStream internalEntryStream
;
40 // This field is just to prevent try with resources error and keep the code
41 // similar to the original
42 private InputStream fInputStream
;
45 * Create a new TarFile for the given file.
47 * @param file the file
48 * @throws IOException on i/o error (bad format, etc)
50 public TarFile(File file
) throws IOException
{
53 fInputStream
= new FileInputStream(file
);
54 // First, check if it's a GZIPInputStream.
56 fInputStream
= new GzipCompressorInputStream(fInputStream
);
57 } catch (IOException e
) {
58 //If it is not compressed we close
59 //the old one and recreate
61 fInputStream
= new FileInputStream(file
);
63 entryEnumerationStream
= new TarArchiveInputStream(fInputStream
);
65 curEntry
= (TarArchiveEntry
) entryEnumerationStream
.getNextEntry();
66 if (curEntry
== null || !curEntry
.isCheckSumOK()) {
67 throw new IOException("Error detected parsing initial entry header"); //$NON-NLS-1$
69 } catch (IOException e
) {
76 * Close the tar file input stream.
78 * @throws IOException if the file cannot be successfully closed
80 public void close() throws IOException
{
81 if (entryEnumerationStream
!= null) {
82 entryEnumerationStream
.close();
84 if (internalEntryStream
!= null) {
85 internalEntryStream
.close();
90 * Create a new TarFile for the given path name.
92 * @param filename the file name to create the TarFile from
93 * @throws IOException on i/o error (bad format, etc)
95 public TarFile(String filename
) throws IOException
{
96 this(new File(filename
));
100 * Returns an enumeration cataloguing the tar archive.
102 * @return enumeration of all files in the archive
104 public Enumeration
<TarArchiveEntry
> entries() {
105 return new Enumeration
<TarArchiveEntry
>() {
107 public boolean hasMoreElements() {
108 return (curEntry
!= null);
112 public TarArchiveEntry
nextElement() {
113 TarArchiveEntry oldEntry
= curEntry
;
115 curEntry
= (TarArchiveEntry
) entryEnumerationStream
.getNextEntry();
116 } catch(IOException e
) {
125 * Returns a new InputStream for the given file in the tar archive.
127 * @param entry the entry to get the InputStream from
128 * @return an input stream for the given file
129 * @throws IOException on i/o error (bad format, etc)
131 public InputStream
getInputStream(TarArchiveEntry entry
) throws IOException
{
132 if(entryStream
== null || !skipToEntry(entryStream
, entry
)) {
133 if (internalEntryStream
!= null) {
134 internalEntryStream
.close();
136 internalEntryStream
= new FileInputStream(file
);
137 // First, check if it's a GzipCompressorInputStream.
139 internalEntryStream
= new GzipCompressorInputStream(internalEntryStream
);
140 } catch(IOException e
) {
141 //If it is not compressed we close
142 //the old one and recreate
143 internalEntryStream
.close();
144 internalEntryStream
= new FileInputStream(file
);
146 entryStream
= new TarArchiveInputStream(internalEntryStream
) {
148 public void close() {
149 // Ignore close() since we want to reuse the stream.
152 skipToEntry(entryStream
, entry
);
157 private static boolean skipToEntry(TarArchiveInputStream entryStream
, TarArchiveEntry entry
) throws IOException
{
158 TarArchiveEntry e
= entryStream
.getNextTarEntry();
160 if (e
.equals(entry
)) {
164 e
= entryStream
.getNextTarEntry();
171 * Returns the path name of the file this archive represents.
175 public String
getName() {
176 return file
.getPath();
180 protected void finalize() throws Throwable
{