1616 */
1717package org .apache .commons .vfs2 .provider .tar ;
1818
19- import java .io .File ;
20- import java .io .IOException ;
21- import java .io .InputStream ;
22- import java .nio .file .Files ;
23- import java .util .Collection ;
24- import java .util .HashMap ;
25- import java .util .Map ;
26- import java .util .Objects ;
27- import java .util .zip .GZIPInputStream ;
28-
2919import org .apache .commons .compress .archivers .ArchiveEntry ;
3020import org .apache .commons .compress .archivers .tar .TarArchiveEntry ;
3121import org .apache .commons .compress .archivers .tar .TarArchiveInputStream ;
4434import org .apache .commons .vfs2 .provider .UriParser ;
4535import org .apache .commons .vfs2 .provider .bzip2 .Bzip2FileObject ;
4636
37+ import java .io .File ;
38+ import java .io .IOException ;
39+ import java .io .InputStream ;
40+ import java .nio .file .Files ;
41+ import java .util .Collection ;
42+ import java .util .HashMap ;
43+ import java .util .Map ;
44+ import java .util .Objects ;
45+ import java .util .zip .GZIPInputStream ;
46+
4747/**
4848 * A read-only file system for Tar files.
4949 */
@@ -54,7 +54,53 @@ public class TarFileSystem extends AbstractFileSystem {
5454
5555 private final File file ;
5656
57- private TarArchiveInputStream tarFile ;
57+ private TarFileThreadLocal tarFile = new TarFileThreadLocal ();
58+
59+ private class TarFileThreadLocal {
60+
61+ private ThreadLocal <Boolean > isPresent = new ThreadLocal <Boolean >() {
62+ @ Override
63+ protected Boolean initialValue () {
64+ return Boolean .FALSE ;
65+ }
66+ };
67+ private ThreadLocal <TarArchiveInputStream > tarFile = new ThreadLocal <TarArchiveInputStream >() {
68+ @ Override
69+ public TarArchiveInputStream initialValue () {
70+ if (isPresent .get ()) {
71+ throw new IllegalStateException ("Creating an initial value but we already have one" );
72+ }
73+ try {
74+ isPresent .set (Boolean .TRUE );
75+ return createTarFile (TarFileSystem .this .file );
76+ } catch (FileSystemException fse ) {
77+ throw new RuntimeException (fse );
78+ }
79+ }
80+ };
81+
82+ public TarArchiveInputStream getFile () throws FileSystemException {
83+ try {
84+ return tarFile .get ();
85+ } catch (RuntimeException e ) {
86+ if (e .getCause () instanceof FileSystemException ) {
87+ throw new FileSystemException (e .getCause ());
88+ }
89+ else {
90+ throw new RuntimeException (e );
91+ }
92+ }
93+ }
94+
95+ public void closeFile () throws IOException {
96+ if (isPresent .get ()) {
97+ TarArchiveInputStream file = tarFile .get ();
98+ file .close ();
99+ tarFile .remove ();
100+ isPresent .set (Boolean .FALSE );
101+ }
102+ }
103+ }
58104
59105 /**
60106 * Cache doesn't need to be synchronized since it is read-only.
@@ -117,10 +163,7 @@ protected TarFileObject createTarFileObject(final AbstractFileName name, final T
117163 protected void doCloseCommunicationLink () {
118164 // Release the tar file
119165 try {
120- if (tarFile != null ) {
121- tarFile .close ();
122- tarFile = null ;
123- }
166+ tarFile .closeFile ();
124167 } catch (final IOException e ) {
125168 // getLogger().warn("vfs.provider.tar/close-tar-file.error :" + file, e);
126169 VfsLog .warn (getLogger (), LOG , "vfs.provider.tar/close-tar-file.error :" + file , e );
@@ -147,6 +190,7 @@ public InputStream getInputStream(final TarArchiveEntry entry) throws FileSystem
147190 resetTarFile ();
148191 try {
149192 ArchiveEntry next ;
193+ TarArchiveInputStream tarFile = getTarFile ();
150194 while ((next = tarFile .getNextEntry ()) != null ) {
151195 if (next .equals (entry )) {
152196 return tarFile ;
@@ -159,10 +203,7 @@ public InputStream getInputStream(final TarArchiveEntry entry) throws FileSystem
159203 }
160204
161205 protected TarArchiveInputStream getTarFile () throws FileSystemException {
162- if (tarFile == null && this .file .exists ()) {
163- recreateTarFile ();
164- }
165- return tarFile ;
206+ return tarFile .getFile ();
166207 }
167208
168209 @ Override
@@ -225,15 +266,12 @@ protected void putFileToCache(final FileObject file) {
225266 */
226267
227268 private void recreateTarFile () throws FileSystemException {
228- if (this .tarFile != null ) {
229- try {
230- this .tarFile .close ();
231- } catch (final IOException e ) {
232- throw new FileSystemException ("vfs.provider.tar/close-tar-file.error" , file , e );
233- }
234- tarFile = null ;
269+ try {
270+ tarFile .closeFile ();
271+ } catch (final IOException e ) {
272+ throw new FileSystemException ("vfs.provider.tar/close-tar-file.error" , file , e );
235273 }
236- this . tarFile = createTarFile ( this . file );
274+ tarFile . getFile ( );
237275 }
238276
239277 /**
0 commit comments