KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > izforge > izpack > io > FileSpanningInputStream


1 /*
2  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
3  *
4  * http://www.izforge.com/izpack/ http://developer.berlios.de/projects/izpack/
5  *
6  * Copyright 2007 Dennis Reil
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software distributed under the License
14  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
15  * or implied. See the License for the specific language governing permissions and limitations under
16  * the License.
17  */

18 package com.izforge.izpack.io;
19
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.util.zip.GZIPInputStream JavaDoc;
25
26 import com.izforge.izpack.util.Debug;
27
28 /**
29  * An inputstream which transparently spans over multiple volumes. The amount of volumes has to be
30  * specified
31  *
32  * @author Dennis Reil, <Dennis.Reil@reddot.de>
33  */

34 public class FileSpanningInputStream extends InputStream JavaDoc
35 {
36
37     private static final int EOF = -1;
38
39     protected FileInputStream JavaDoc fileinputstream;
40
41     protected String JavaDoc volumename;
42
43     protected int currentvolumeindex;
44
45     protected int volumestotal;
46
47     protected static boolean nextvolumenotfound = false;
48
49     protected long filepointer;
50
51     protected GZIPInputStream JavaDoc zippedinputstream;
52
53     public FileSpanningInputStream(File JavaDoc volume, int volumestotal) throws IOException JavaDoc
54     {
55         fileinputstream = new FileInputStream JavaDoc(volume);
56         zippedinputstream = new GZIPInputStream JavaDoc(fileinputstream);
57         currentvolumeindex = 0;
58         volumename = volume.getAbsolutePath();
59         this.volumestotal = volumestotal;
60         filepointer = 0;
61         Debug.trace("Opening stream to " + volume);
62     }
63
64     public FileSpanningInputStream(String JavaDoc volumename, int volumestotal) throws IOException JavaDoc
65     {
66         this(new File JavaDoc(volumename), volumestotal);
67     }
68
69     /**
70      * creates an inputstream to the next volume
71      *
72      * @return true - an inputstream to the next volume has been created false - the last volume was
73      * reached
74      * @throws IOException
75      */

76     private boolean createInputStreamToNextVolume() throws IOException JavaDoc
77     {
78         currentvolumeindex++;
79         // have we reached the last volume?
80
if (currentvolumeindex >= volumestotal)
81         {
82             Debug.error("last volume reached.");
83             return false;
84         }
85         // the next volume name
86
String JavaDoc nextvolumename = volumename + "." + currentvolumeindex;
87         Debug.trace("Trying to use next volume: " + nextvolumename);
88         File JavaDoc nextvolumefile = new File JavaDoc(nextvolumename);
89         if (!nextvolumefile.exists())
90         {
91             currentvolumeindex--;
92             nextvolumenotfound = true;
93             Debug.trace("volume not found");
94             throw new VolumeNotFoundException(nextvolumename + "was not found.", nextvolumename);
95         }
96         Debug.trace("next volume found.");
97         // try to open new stream to next volume
98
fileinputstream = new FileInputStream JavaDoc(nextvolumefile);
99         zippedinputstream = new GZIPInputStream JavaDoc(fileinputstream);
100         // everything fine
101
nextvolumenotfound = false;
102         return true;
103     }
104
105     /*
106      * (non-Javadoc)
107      *
108      * @see java.io.InputStream#available()
109      */

110     public int available() throws IOException JavaDoc
111     {
112         if (nextvolumenotfound)
113         {
114             createInputStreamToNextVolume();
115         }
116         // return fileinputstream.available();
117
return zippedinputstream.available();
118     }
119
120     /*
121      * (non-Javadoc)
122      *
123      * @see java.io.InputStream#close()
124      */

125     public void close() throws IOException JavaDoc
126     {
127         zippedinputstream.close();
128         fileinputstream.close();
129     }
130
131     /*
132      * (non-Javadoc)
133      *
134      * @see java.io.InputStream#read()
135      */

136     public int read() throws IOException JavaDoc
137     {
138         if (nextvolumenotfound)
139         {
140             // the next volume was not found, so try to create a new input stream to next volume
141
createInputStreamToNextVolume();
142         }
143         int nextbyte = zippedinputstream.read();
144         filepointer++;
145         if (nextbyte == EOF)
146         {
147             // if end of file is reached, try to open InputStream to next volume
148
// close the inputstream
149
try
150             {
151                 zippedinputstream.close();
152             }
153             catch (Exception JavaDoc e)
154             {
155                 // do nothing
156
}
157
158             if (createInputStreamToNextVolume())
159             {
160                 // try to read next byte
161
nextbyte = zippedinputstream.read();
162                 filepointer++;
163             }
164         }
165         return nextbyte;
166     }
167
168     /*
169      * (non-Javadoc)
170      *
171      * @see java.io.InputStream#read(byte[], int, int)
172      */

173     public int read(byte[] b, int off, int len) throws IOException JavaDoc
174     {
175         if (nextvolumenotfound)
176         {
177             // the next volume was not found, so try to create a new input stream to next volume
178
createInputStreamToNextVolume();
179         }
180         int bytesread = zippedinputstream.read(b, off, len);
181         filepointer += bytesread;
182         if (bytesread == EOF)
183         {
184             filepointer++; // bytesread was -1;
185
System.out.println("EOF reached.");
186             // close the inputstream
187
try
188             {
189                 zippedinputstream.close();
190             }
191             catch (Exception JavaDoc e)
192             {
193                 // do nothing
194
}
195             // try to open next volume
196
if (createInputStreamToNextVolume())
197             {
198                 // try to read next bytes
199
Debug.trace("next volume opened, continuing read");
200                 bytesread = zippedinputstream.read(b, off, len);
201                 filepointer += bytesread;
202                 // System.out.println("read into buffer: " + bytesread + " Bytes");
203
}
204         }
205         // System.out.println("return from read into buffer: " + bytesread + " Bytes");
206
return bytesread;
207     }
208
209     /*
210      * (non-Javadoc)
211      *
212      * @see java.io.InputStream#read(byte[])
213      */

214     public int read(byte[] b) throws IOException JavaDoc
215     {
216         return this.read(b, 0, b.length);
217     }
218
219     /*
220      * (non-Javadoc)
221      *
222      * @see java.io.InputStream#skip(long)
223      */

224     public long skip(long n) throws IOException JavaDoc
225     {
226         if (nextvolumenotfound)
227         {
228             // the next volume was not found, so try to create a new input stream to next volume
229
createInputStreamToNextVolume();
230         }
231         long bytesskipped = 0;
232         byte[] buffer = new byte[4096];
233         try
234         {
235             while (bytesskipped < n)
236             {
237                 int maxBytes = (int) Math.min(n - bytesskipped, buffer.length);
238
239                 int bytesInBuffer = this.read(buffer, 0, maxBytes);
240                 if (bytesInBuffer == -1)
241                     throw new IOException JavaDoc("Unexpected end of stream (installer corrupted?)");
242
243                 bytesskipped += bytesInBuffer;
244             }
245         }
246         catch (VolumeNotFoundException vnfe)
247         {
248             vnfe.setAlreadyskippedbytes(bytesskipped);
249             throw vnfe;
250         }
251         return bytesskipped;
252     }
253
254     /**
255      * Returns the name of the volume
256      *
257      * @return the name of the volume
258      */

259     public String JavaDoc getVolumename()
260     {
261         return volumename;
262     }
263
264     /**
265      * Sets the volumename
266      *
267      * @param volumename
268      */

269     public void setVolumename(String JavaDoc volumename)
270     {
271         Debug.trace("new volumename: " + volumename);
272         // try to get the volumename from the given volume file
273
// the first volume has no suffix, additional volumes have a .INDEX# suffix
274
String JavaDoc volumesuffix = "." + currentvolumeindex;
275         String JavaDoc nextvolumesuffix = "." + (currentvolumeindex + 1);
276         if (volumename.endsWith(volumesuffix))
277         {
278             this.volumename = volumename.substring(0, volumename.lastIndexOf(volumesuffix));
279         }
280         else if (volumename.endsWith(nextvolumesuffix))
281         {
282             this.volumename = volumename.substring(0, volumename.lastIndexOf(nextvolumesuffix));
283         }
284         else
285         {
286             this.volumename = volumename;
287         }
288         Debug.trace("Set volumename to: " + this.volumename);
289     }
290
291     /**
292      * Returns the current position in the file. Notice: this is the global position in all volumes.
293      *
294      * @return the current position in file.
295      */

296     public long getFilepointer()
297     {
298         return filepointer;
299     }
300
301 }
302
Popular Tags