KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > store > StreamFile


1 /**
2  * com.mckoi.store.StreamFile 17 Jun 2003
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.store;
26
27 import java.io.*;
28
29 /**
30  * A RandomAccessFile that acts as an OutputStream, and can also be read as an
31  * InputStream.
32  *
33  * @author Tobias Downer
34  */

35
36 public class StreamFile {
37
38   /**
39    * The File object.
40    */

41   private final File file;
42   
43   /**
44    * The RandomAccessFile.
45    */

46   private RandomAccessFile data;
47   
48   /**
49    * Pointer to the end of the file.
50    */

51   private long end_pointer;
52
53   /**
54    * The OutputStream object for this file.
55    */

56   private OutputStream output_stream;
57   
58   /**
59    * Constructor.
60    */

61   public StreamFile(File file, String JavaDoc mode) throws IOException {
62     this.file = file;
63     data = new RandomAccessFile(file, mode);
64     end_pointer = data.length();
65     output_stream = new SFOutputStream();
66   }
67
68   /**
69    * Closes the file.
70    */

71   public void close() throws IOException {
72     synchronized (data) {
73       data.close();
74     }
75   }
76   
77   /**
78    * Synchs the file.
79    */

80   public void synch() throws IOException {
81     synchronized (data) {
82       try {
83         data.getFD().sync();
84       }
85       catch (SyncFailedException e) {
86         // A SyncFailedException seems to occur on some specific OS under
87
// JDK 1.4.x. We ignore the exception which reduces the robustness
88
// of the journal file for the OS where this problem occurs.
89
// Unfortunately there's no sane way to handle this excption when it
90
// does occur.
91
}
92     }
93   }
94   
95   /**
96    * Deletes the file.
97    */

98   public void delete() throws IOException {
99     file.delete();
100   }
101   
102   /**
103    * Fully reads a block from a section of the file into the given byte[]
104    * array at the given position.
105    */

106   public void readFully(final long position,
107                         byte[] buf, int off, int len) throws IOException {
108     synchronized (data) {
109       data.seek(position);
110       int to_read = len;
111       while (to_read > 0) {
112         int read = data.read(buf, off, to_read);
113         to_read -= read;
114         off += read;
115       }
116     }
117   }
118   
119   /**
120    * Returns the current length of the data.
121    */

122   public long length() {
123     synchronized (data) {
124       return end_pointer;
125     }
126   }
127
128   /**
129    * Opens an OutputStream to the file. Only one output stream may be open
130    * on the file at once.
131    */

132   public OutputStream getOutputStream() throws IOException {
133     return output_stream;
134   }
135   
136   /**
137    * Returns an InputStream to the file that allows us to read from the start
138    * to the end of the file.
139    */

140   public InputStream getInputStream() throws IOException {
141     return new SFInputStream();
142   }
143
144   // ---------- Inner classes ----------
145

146
147   
148   class SFOutputStream extends OutputStream {
149
150     public void write(int i) throws IOException {
151       synchronized (data) {
152         data.seek(end_pointer);
153         data.write(i);
154         ++end_pointer;
155       }
156     }
157     
158     public void write(byte[] buf, int off, int len) throws IOException {
159       if (len > 0) {
160         synchronized (data) {
161           data.seek(end_pointer);
162           data.write(buf, off, len);
163           end_pointer += len;
164         }
165       }
166     }
167
168   }
169
170
171
172   class SFInputStream extends InputStream {
173
174     private long fp = 0;
175
176     public int read() throws IOException {
177       synchronized (data) {
178         if (fp >= end_pointer) {
179           return -1;
180         }
181         data.seek(fp);
182         ++fp;
183         return data.read();
184
185       }
186     }
187
188     public int read(byte[] buf, int off, int len) throws IOException {
189       synchronized (data) {
190         if (len == 0) {
191           return 0;
192         }
193         len = (int) Math.min((long) len, end_pointer - fp);
194         if (len <= 0) {
195           return -1;
196         }
197
198         data.seek(fp);
199         int act_read = data.read(buf, off, len);
200         fp += act_read;
201         return act_read;
202       }
203     }
204
205     public long skip(long v) throws IOException {
206       synchronized (data) {
207         fp += v;
208       }
209       return v;
210     }
211
212   }
213
214 }
215
216
Popular Tags