KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > io > FileInputStream


1 /*
2  * FileInputStream.java
3  *
4  * Created on 24. Oktober 2004, 13:06
5  */

6 /*
7  * Copyright 2005 Schlichtherle IT Services
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package de.schlichtherle.io;
23
24 import java.io.FileDescriptor JavaDoc;
25 import java.io.FilterInputStream JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.FileNotFoundException JavaDoc;
29
30 /**
31  * A <em>drop-in-replacement</em> for <code>java.io.FileInputStream</code>
32  * which provides transparent access to archive files as if they were just
33  * directories in a path name.
34  * To read an entry in an archive file, simply create an instance
35  * of this class with a path name that contains the archive file as one
36  * of the parent directories.
37  * The remainder of the path name will then be used as the relative path
38  * of the entry in the archive file to be read.
39  * <p>
40  * For example on UNIX like systems using the path
41  * <code>/home/user/archive.zip/directory/readme</code> will read
42  * the relative path <code>directory/readme</code> in ZIP file
43  * <code>/home/user/archive.zip</code>.
44  * <p>
45  * To prevent an exception to be thrown subsequently, client applications
46  * must make sure to close their streams using the following idiom:
47  * <code>
48  * <pre>
49  * FileInputStream fis = new FileInputStream(file);
50  * try {
51  * // access fis here
52  * } finally {
53  * fis.close();
54  * }
55  * </pre>
56  * </code>
57  * Client applications should <em>always</em> use this idiom for any streams
58  * to ensure that subsequent operations like {@link File#umount} may succeed.
59  * <p>
60  * Note that this issue is not at all specific to this class:
61  * File descriptors are limited resources on any operating system and some
62  * operating systems even restrict a process from using certain file
63  * operations if the file is busy on I/O by another process.
64  * E.g. on Windows, a process cannot delete a file that is open for I/O
65  * by any other process.
66  *
67  * <h3>Important</h3>
68  * <ol>
69  * <li>The classes in this package access and manipulate archive files as
70  * external resources and may cache some of their state in memory and
71  * temporary files. Third parties must not concurrently access these
72  * archive files unless some precautions have been taken!
73  * For more information please refer to the
74  * <a HREF="package-summary.html#third_party_access">Third Party Access</a>
75  * section in the package description.
76  * <li>Client applications cannot read from an entry in an archive file if an
77  * automatic update is required but cannot be performed because the
78  * application is still using other <code>FileInputStream</code> or
79  * <code>FileOutputStream</code> instances which haven't been closed or
80  * discarded yet.
81  * Failure to comply to this restriction will result in a
82  * <code>FileBusyException</code> to be thrown by the constructors of this
83  * class.
84  * Client applications may call {@link File#umount} or {@link File#update}
85  * to force the other streams to be closed and recreate this stream again
86  * to resolve the issue.
87  * <li>Whether or not a client application can read from more than one entry
88  * in the same archive archive file concurrently is an implementation
89  * detail of the respective archive driver.
90  * TrueZIP's implementation of the ZIP32 and TAR driver families does not
91  * limit this.
92  * However, other driver implementations may do so.
93  * <p>
94  * If a client application tries to exceed the number of entry streams
95  * supported to operate on the same archive file concurrently, a
96  * {@link FileBusyException} is thrown by the constructors of this class.
97  * In this case, the client application may close (or discard and rely
98  * on the finalizer thread) the previously created stream objects or
99  * call {@link File#umount()} or {@link File#update()} to force these
100  * streams to be closed and then recreate this stream object again to
101  * resolve the issue.
102  * </ol>
103  *
104  * <h3>Miscellaneous</h3>
105  * <ol>
106  * <li>If you would like to use this class in order to copy files,
107  * please consider using the <code>*copy*</code> methods in the {@link File}
108  * class instead. These offer advanced fail-safety and performance features.
109  * <li>If you have configured TrueZIP to use a <em>checked</em> driver for ZIP
110  * compatible files (the class
111  * {@link de.schlichtherle.io.archive.zip.CheckedZip32Driver} for example)
112  * and there is a mismatch of the CRC-32 values for the ZIP entry
113  * addressed by this input stream, the <code>close()</code> method
114  * will throw a {@link de.schlichtherle.util.zip.CRC32Exception}.
115  * Other than this, the ZIP entry will be processed normally.
116  * So if just the CRC-32 value for the entry in the ZIP file has been
117  * modified, you can still read its contents.
118  * <li>Please refer to the {@link java.io.FileInputStream super class
119  * documentation} for any undocumented methods.
120  * </ol>
121  *
122  * @see FileBusyException
123  * @see File#update
124  * @see File#umount
125  * @see File#setLenient
126  * @see java.io.FileInputStream java.io.FileInputStream
127  * @see <a HREF="package-summary.html#package_description">Package Description</a>
128  * @author Christian Schlichtherle
129  * @version @version@
130  */

131 public class FileInputStream extends FilterInputStream JavaDoc {
132
133     private static InputStream JavaDoc createInputStream(final java.io.File JavaDoc file)
134             throws FileNotFoundException JavaDoc {
135         if (file instanceof File) {
136             final File smartFile = (File) file;
137             smartFile.ensureNotVirtualDirectory("cannot read");
138             final String JavaDoc entryName = smartFile.getEnclEntryName();
139             if (entryName != null)
140                 return createInputStream(
141                         smartFile.getEnclArchive().getArchiveController(),
142                         entryName, smartFile);
143         }
144         return new java.io.FileInputStream JavaDoc(file);
145     }
146
147     private static InputStream JavaDoc createInputStream(
148             final ArchiveController controller,
149             final String JavaDoc entryName,
150             final File file)
151             throws FileNotFoundException JavaDoc {
152         try {
153             return controller.getInputStream(entryName);
154         } catch (ArchiveController.FalsePositiveNativeException failure) {
155             final java.io.File JavaDoc delegate = file.getDelegate();
156             if (delegate.exists() && !delegate.isDirectory()) // file or special file
157
return new java.io.FileInputStream JavaDoc(file);
158             else
159                 throw failure;
160         }
161     }
162
163     /**
164      * Behaves like the super class, but also supports archive entry files.
165      *
166      * @see java.io.FileInputStream java.io.FileInputStream
167      */

168     public FileInputStream(String JavaDoc name)
169     throws FileNotFoundException JavaDoc {
170         super(createInputStream(File.getDefaultArchiveDetector().createFile(name)));
171     }
172
173     /**
174      * Behaves like the super class, but also supports archive entry files.
175      *
176      * @see java.io.FileInputStream java.io.FileInputStream
177      */

178     public FileInputStream(java.io.File JavaDoc file)
179     throws FileNotFoundException JavaDoc {
180         super(createInputStream(file));
181     }
182
183     /**
184      * @see java.io.FileInputStream java.io.FileInputStream
185      * @since TrueZIP 6.4
186      */

187     public FileInputStream(FileDescriptor JavaDoc fd) {
188         super(new java.io.FileInputStream JavaDoc(fd));
189     }
190
191     public int read(byte b[]) throws IOException JavaDoc {
192         return in.read(b, 0, b.length);
193     }
194 }
195
Popular Tags