001: /*
002: Copyright (C) 2007 Mobixess Inc. http://www.java-objects-database.com
003:
004: This file is part of the JODB (Java Objects Database) open source project.
005:
006: JODB is free software; you can redistribute it and/or modify it under
007: the terms of version 2 of the GNU General Public License as published
008: by the Free Software Foundation.
009:
010: JODB is distributed in the hope that it will be useful, but WITHOUT ANY
011: WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
013: for more details.
014:
015: You should have received a copy of the GNU General Public License along
016: with this program; if not, write to the Free Software Foundation, Inc.,
017: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: */
019: package com.mobixess.jodb.core.io.buffers;
020:
021: import java.io.File;
022: import java.io.IOException;
023: import java.io.RandomAccessFile;
024: import java.nio.channels.AsynchronousCloseException;
025: import java.nio.channels.ByteChannel;
026: import java.nio.channels.ClosedByInterruptException;
027: import java.nio.channels.ClosedChannelException;
028: import java.nio.channels.NonReadableChannelException;
029: import java.nio.channels.NonWritableChannelException;
030: import java.nio.channels.ReadableByteChannel;
031: import java.nio.channels.WritableByteChannel;
032:
033: import com.mobixess.jodb.core.io.IRandomAccessDataBuffer;
034:
035: public class RandomAccessFileTransactionBuffer implements
036: IRandomAccessDataBuffer {
037:
038: private File _file;
039: private RandomAccessFile _raFile;
040:
041: /*package*/RandomAccessFileTransactionBuffer(File file,
042: boolean write) throws IOException {
043: super ();
044: _file = file;
045: _raFile = new RandomAccessFile(_file, "r" + (write ? "w" : ""));
046: }
047:
048: /**
049: * @param file
050: * @param raFile
051: */
052: // public RandomAccessFileTransactionBuffer(File file, RandomAccessFile raFile) {
053: // super();
054: // _file = file;
055: // _raFile = raFile;
056: // }
057:
058: public void close() throws IOException {
059: _raFile.close();
060: }
061:
062: public void delete() throws IOException {
063: close();
064: _file.delete();
065: }
066:
067: public ByteChannel getChannel() {
068: return _raFile.getChannel();
069: }
070:
071: public long getCursorOffset() throws IOException {
072: return _raFile.getFilePointer();
073: }
074:
075: public long length() throws IOException {
076: return _raFile.length();
077: }
078:
079: public void seek(long pos) throws IOException {
080: _raFile.seek(pos);
081: }
082:
083: public void setLength(long newLength) throws IOException {
084: _raFile.setLength(newLength);
085: }
086:
087: /**
088: * Transfers bytes into this channel's file from the given readable byte
089: * channel.
090: *
091: * <p> An attempt is made to read up to <tt>count</tt> bytes from the
092: * source channel and write them to this channel's file starting at the
093: * given <tt>position</tt>. An invocation of this method may or may not
094: * transfer all of the requested bytes; whether or not it does so depends
095: * upon the natures and states of the channels. Fewer than the requested
096: * number of bytes will be transferred if the source channel has fewer than
097: * <tt>count</tt> bytes remaining, or if the source channel is non-blocking
098: * and has fewer than <tt>count</tt> bytes immediately available in its
099: * input buffer.
100: *
101: * <p> This method does not modify this channel's position. If the given
102: * position is greater than the file's current size then no bytes are
103: * transferred. If the source channel has a position then bytes are read
104: * starting at that position and then the position is incremented by the
105: * number of bytes read.
106: *
107: * <p> This method is potentially much more efficient than a simple loop
108: * that reads from the source channel and writes to this channel. Many
109: * operating systems can transfer bytes directly from the source channel
110: * into the filesystem cache without actually copying them. </p>
111: *
112: * @param src
113: * The source channel
114: *
115: * @param position
116: * The position within the file at which the transfer is to begin;
117: * must be non-negative
118: *
119: * @param count
120: * The maximum number of bytes to be transferred; must be
121: * non-negative
122: *
123: * @return The number of bytes, possibly zero,
124: * that were actually transferred
125: *
126: * @throws IllegalArgumentException
127: * If the preconditions on the parameters do not hold
128: *
129: * @throws NonReadableChannelException
130: * If the source channel was not opened for reading
131: *
132: * @throws NonWritableChannelException
133: * If this channel was not opened for writing
134: *
135: * @throws ClosedChannelException
136: * If either this channel or the source channel is closed
137: *
138: * @throws AsynchronousCloseException
139: * If another thread closes either channel
140: * while the transfer is in progress
141: *
142: * @throws ClosedByInterruptException
143: * If another thread interrupts the current thread while the
144: * transfer is in progress, thereby closing both channels and
145: * setting the current thread's interrupt status
146: *
147: * @throws IOException
148: * If some other I/O error occurs
149: */
150: public long transferFrom(ReadableByteChannel src, long position,
151: long count) throws IOException {
152: return _raFile.getChannel().transferFrom(src, position, count);
153: }
154:
155: /**
156: * Transfers bytes from this channel's file to the given writable byte
157: * channel.
158: *
159: * <p> An attempt is made to read up to <tt>count</tt> bytes starting at
160: * the given <tt>position</tt> in this channel's file and write them to the
161: * target channel. An invocation of this method may or may not transfer
162: * all of the requested bytes; whether or not it does so depends upon the
163: * natures and states of the channels. Fewer than the requested number of
164: * bytes are transferred if this channel's file contains fewer than
165: * <tt>count</tt> bytes starting at the given <tt>position</tt>, or if the
166: * target channel is non-blocking and it has fewer than <tt>count</tt>
167: * bytes free in its output buffer.
168: *
169: * <p> This method does not modify this channel's position. If the given
170: * position is greater than the file's current size then no bytes are
171: * transferred. If the target channel has a position then bytes are
172: * written starting at that position and then the position is incremented
173: * by the number of bytes written.
174: *
175: * <p> This method is potentially much more efficient than a simple loop
176: * that reads from this channel and writes to the target channel. Many
177: * operating systems can transfer bytes directly from the filesystem cache
178: * to the target channel without actually copying them. </p>
179: *
180: * @param position
181: * The position within the file at which the transfer is to begin;
182: * must be non-negative
183: *
184: * @param count
185: * The maximum number of bytes to be transferred; must be
186: * non-negative
187: *
188: * @param target
189: * The target channel
190: *
191: * @return The number of bytes, possibly zero,
192: * that were actually transferred
193: *
194: * @throws IllegalArgumentException
195: * If the preconditions on the parameters do not hold
196: *
197: * @throws NonReadableChannelException
198: * If this channel was not opened for reading
199: *
200: * @throws NonWritableChannelException
201: * If the target channel was not opened for writing
202: *
203: * @throws ClosedChannelException
204: * If either this channel or the target channel is closed
205: *
206: * @throws AsynchronousCloseException
207: * If another thread closes either channel
208: * while the transfer is in progress
209: *
210: * @throws ClosedByInterruptException
211: * If another thread interrupts the current thread while the
212: * transfer is in progress, thereby closing both channels and
213: * setting the current thread's interrupt status
214: *
215: * @throws IOException
216: * If some other I/O error occurs
217: */
218: public long transferTo(long position, long count,
219: WritableByteChannel target) throws IOException {
220: return _raFile.getChannel().transferTo(position, count, target);
221: }
222:
223: public boolean readBoolean() throws IOException {
224: return _raFile.readBoolean();
225: }
226:
227: public byte readByte() throws IOException {
228:
229: return _raFile.readByte();
230: }
231:
232: public char readChar() throws IOException {
233:
234: return _raFile.readChar();
235: }
236:
237: public double readDouble() throws IOException {
238:
239: return _raFile.readDouble();
240: }
241:
242: public float readFloat() throws IOException {
243:
244: return _raFile.readFloat();
245: }
246:
247: public void readFully(byte[] b) throws IOException {
248:
249: _raFile.readFully(b);
250: }
251:
252: public void readFully(byte[] b, int off, int len)
253: throws IOException {
254:
255: _raFile.read(b, off, len);
256: }
257:
258: public int readInt() throws IOException {
259:
260: return _raFile.readInt();
261: }
262:
263: public String readLine() throws IOException {
264:
265: return _raFile.readLine();
266: }
267:
268: public long readLong() throws IOException {
269:
270: return _raFile.readLong();
271: }
272:
273: public short readShort() throws IOException {
274:
275: return _raFile.readShort();
276: }
277:
278: public String readUTF() throws IOException {
279:
280: return _raFile.readUTF();
281: }
282:
283: public int readUnsignedByte() throws IOException {
284:
285: return _raFile.readUnsignedByte();
286: }
287:
288: public int readUnsignedShort() throws IOException {
289:
290: return _raFile.readUnsignedShort();
291: }
292:
293: public int skipBytes(int n) throws IOException {
294:
295: return _raFile.skipBytes(n);
296: }
297:
298: public void write(int b) throws IOException {
299:
300: _raFile.write(b);
301: }
302:
303: public void write(byte[] b) throws IOException {
304:
305: _raFile.write(b);
306: }
307:
308: public void write(byte[] b, int off, int len) throws IOException {
309:
310: _raFile.write(b, off, len);
311: }
312:
313: public void writeBoolean(boolean v) throws IOException {
314:
315: _raFile.writeBoolean(v);
316: }
317:
318: public void writeByte(int v) throws IOException {
319:
320: _raFile.writeByte(v);
321: }
322:
323: public void writeBytes(String s) throws IOException {
324:
325: _raFile.writeBytes(s);
326: }
327:
328: public void writeChar(int v) throws IOException {
329:
330: _raFile.writeChar(v);
331: }
332:
333: public void writeChars(String s) throws IOException {
334:
335: _raFile.writeChars(s);
336: }
337:
338: public void writeDouble(double v) throws IOException {
339:
340: _raFile.writeDouble(v);
341: }
342:
343: public void writeFloat(float v) throws IOException {
344:
345: _raFile.writeFloat(v);
346: }
347:
348: public void writeInt(int v) throws IOException {
349:
350: _raFile.writeInt(v);
351: }
352:
353: public void writeLong(long v) throws IOException {
354:
355: _raFile.writeLong(v);
356: }
357:
358: public void writeShort(int v) throws IOException {
359:
360: _raFile.writeShort(v);
361: }
362:
363: public void writeUTF(String str) throws IOException {
364:
365: _raFile.writeUTF(str);
366: }
367:
368: public void resetToStart() throws IOException {
369: _raFile.seek(0);
370: }
371:
372: public void read(byte[] b, int off, int len) throws IOException {
373: _raFile.read(b, off, len);
374: }
375:
376: public void resetToEnd() throws IOException {
377: _raFile.seek(_raFile.length());
378: }
379:
380: public long skip(long n) throws IOException {
381: long totalSkiped = 0;
382: while (n > 0) {
383: int skiped = _raFile.skipBytes((int) Math.min(n,
384: Integer.MAX_VALUE));
385: if (skiped == 0) {
386: return totalSkiped;
387: }
388: totalSkiped += skiped;
389: n -= skiped;
390: }
391: return 0;
392: }
393:
394: @Override
395: public String toString() {
396: try {
397: return "transaction buffer length=" + length()
398: + " pointer=" + getCursorOffset() + " " + _raFile;
399: } catch (IOException e) {
400: return super .toString();
401: }
402: }
403:
404: public void prefetch(long offset) throws IOException {
405: }
406:
407: }
|