KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * com.mckoi.store.IOStoreDataAccessor 10 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.File JavaDoc;
28 import java.io.SyncFailedException JavaDoc;
29 import java.io.RandomAccessFile JavaDoc;
30 import java.io.IOException JavaDoc;
31
32 /**
33  * An implementation of StoreDataAccessor that uses the standard Java IO API to
34  * access data in some underlying file in the filesystem.
35  *
36  * @author Tobias Downer
37  */

38
39 class IOStoreDataAccessor implements StoreDataAccessor {
40
41   /**
42    * A lock because access to the data is stateful.
43    */

44   private Object JavaDoc lock = new Object JavaDoc();
45
46   /**
47    * The File object representing the file in the file system.
48    */

49   private File JavaDoc file;
50   
51   /**
52    * The underlying RandomAccessFile containing the data.
53    */

54   private RandomAccessFile JavaDoc data;
55
56   /**
57    * The size of the data area.
58    */

59   private long size;
60   
61   /**
62    * True if the file is open.
63    */

64   private boolean is_open;
65   
66   /**
67    * Constructor.
68    */

69   IOStoreDataAccessor(File JavaDoc file) {
70     this.file = file;
71     this.is_open = false;
72   }
73   
74   // ---------- Implemented from StoreDataAccessor ----------
75

76   public void open(boolean is_read_only) throws IOException JavaDoc {
77     synchronized (lock) {
78       data = new RandomAccessFile JavaDoc(file, is_read_only ? "r" : "rw");
79       size = file.length();
80       is_open = true;
81     }
82   }
83
84   public void close() throws IOException JavaDoc {
85     synchronized (lock) {
86       data.close();
87       data = null;
88       is_open = false;
89     }
90   }
91   
92   public boolean delete() {
93     if (!is_open) {
94       return file.delete();
95     }
96     return false;
97   }
98
99   public boolean exists() {
100     return file.exists();
101   }
102   
103
104   public void read(long position, byte[] buf, int off, int len)
105                                                           throws IOException JavaDoc {
106     // Make sure we don't read past the end
107
synchronized (lock) {
108       len = Math.max(0, Math.min(len, (int) (size - position)));
109       if (position < size) {
110         data.seek(position);
111         data.readFully(buf, off, len);
112       }
113     }
114   }
115
116   public void write(long position, byte[] buf, int off, int len)
117                                                           throws IOException JavaDoc {
118     // Make sure we don't write past the end
119
synchronized (lock) {
120       len = Math.max(0, Math.min(len, (int) (size - position)));
121       if (position < size) {
122         data.seek(position);
123         data.write(buf, off, len);
124       }
125     }
126   }
127
128   public void setSize(long new_size) throws IOException JavaDoc {
129     synchronized (lock) {
130       // If expanding the size of the file,
131
if (new_size > this.size) {
132         // Seek to the new size - 1 and write a single byte to the end of the
133
// file.
134
long p = new_size - 1;
135         if (p > 0) {
136           data.seek(p);
137           data.write(0);
138           this.size = new_size;
139         }
140       }
141       else if (new_size < this.size) {
142         // Otherwise the size of the file is shrinking, so setLength().
143
// Note that we don't use 'setLength' to grow the file because of a
144
// bug in the Linux 1.2, 1.3 and 1.4 JVM that generates an error when
145
// expanding the size of a file via 'setLength' on some file systems
146
// (specifically VFAT).
147
data.setLength(new_size);
148         this.size = new_size;
149       }
150     }
151   }
152
153   public long getSize() throws IOException JavaDoc {
154     synchronized (lock) {
155       if (is_open) {
156         return size;
157       }
158       else {
159         return file.length();
160       }
161     }
162   }
163
164   public void synch() throws IOException JavaDoc {
165     synchronized (lock) {
166       try {
167         data.getFD().sync();
168       }
169       catch (SyncFailedException JavaDoc e) {
170         // There isn't much we can do about this exception. By itself it
171
// doesn't indicate a terminating error so it's a good idea to ignore
172
// it. Should it be silently ignored?
173
}
174     }
175   }
176
177   
178 }
179
180
Popular Tags