1 /*******************************************************************************
\r
2 * Copyright (c) 2016 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * Semantum Oy - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard.util.binary;
14 import java.io.File;
\r
15 import java.io.IOException;
\r
16 import java.nio.ByteBuffer;
\r
19 * This class is a custom write-only wrapper for {@link BinaryFile} and
\r
20 * {@link BinaryMemory} that implements a {@link RandomAccessBinary} which is
\r
21 * contained fully in memory until its size reaches a user-specified threshold.
\r
22 * When that size threshold is exceeded, the {@link BinaryMemory} contents are
\r
23 * flushed into a BinaryFile and from there on this implementation will continue
\r
24 * to write to the BinaryFile.
\r
26 * Since it is based {@link BinaryFile} and {@link BinaryMemory}, this
\r
27 * implementation is also buffered and <em>not</em> thread-safe.
\r
29 * The {@link SeekableBinaryReadable} part of the {@link RandomAccessBinary}
\r
30 * interface is not implemented and will throw
\r
31 * {@link UnsupportedOperationException}.
\r
33 * @author Tuukka Lehtonen
\r
34 * @since 1.22.1 & 1.24.0
\r
38 public class DeferredBinaryFile implements RandomAccessBinary {
44 BinaryMemory memory;
\r
45 RandomAccessBinary backend;
47 public DeferredBinaryFile(File file, int threshold, int fileBufferSize) throws IOException {
\r
48 this.memory = new BinaryMemory(threshold+10000);
\r
49 this.backend = memory;
\r
50 this.threshold = threshold;
\r
52 this.fileBufferSize = fileBufferSize;
\r
56 * Closes the object. Note, this will close the input random access file.
\r
57 * This method may be called several times.
62 public synchronized void close() throws IOException {
\r
63 if (backend == null)
\r
70 public synchronized boolean isOpen() {
\r
71 return backend != null;
\r
75 public byte readByte() throws IOException {
76 throw new UnsupportedOperationException();
\r
80 public char readChar() throws IOException {
\r
81 throw new UnsupportedOperationException();
\r
85 public int readUnsignedByte() throws IOException {
\r
86 throw new UnsupportedOperationException();
\r
90 public boolean readBoolean() throws IOException {
\r
91 throw new UnsupportedOperationException();
\r
95 public void readFully(byte[] dst, int offset, int length) throws IOException {
96 throw new UnsupportedOperationException();
\r
100 public void readFully(byte[] dst) throws IOException {
101 throw new UnsupportedOperationException();
\r
105 public void readFully(ByteBuffer buf) throws IOException {
106 throw new UnsupportedOperationException();
\r
110 public void readFully(ByteBuffer buf, int length) throws IOException {
111 throw new UnsupportedOperationException();
\r
115 public double readDouble() throws IOException {
116 throw new UnsupportedOperationException();
\r
120 public float readFloat() throws IOException {
121 throw new UnsupportedOperationException();
\r
125 public int readInt() throws IOException {
126 throw new UnsupportedOperationException();
\r
130 public long readLong() throws IOException {
131 throw new UnsupportedOperationException();
\r
135 public short readShort() throws IOException {
136 throw new UnsupportedOperationException();
\r
140 public int readUnsignedShort() throws IOException {
\r
141 throw new UnsupportedOperationException();
\r
145 public String readUTF() throws IOException {
\r
146 throw new UnsupportedOperationException();
\r
149 public final String readLine() throws IOException {
\r
150 throw new UnsupportedOperationException();
\r
154 public long position() throws IOException {
155 return backend.position();
\r
159 public void position(long newPosition) throws IOException {
160 backend.position(newPosition);
\r
164 * Flushes internal buffer
167 public void flush() throws IOException {
172 * Clears read&write buffer. The file can be modified elsewhere after this.
174 * @throws IOException
177 public void reset() throws IOException {
182 public long skipBytes(long bytes) throws IOException {
\r
183 return backend.skipBytes(bytes);
\r
187 public int skipBytes(int bytes) throws IOException {
\r
188 return backend.skipBytes(bytes);
\r
195 public void write(int b) throws IOException {
197 if (memory != null)
\r
202 public void writeByte(int b) throws IOException {
\r
203 backend.writeByte(b);
\r
204 if (memory != null)
\r
209 public void writeBoolean(boolean v) throws IOException {
\r
210 backend.writeBoolean(v);
\r
211 if (memory != null)
\r
216 public void writeFully(ByteBuffer src) throws IOException {
217 backend.writeFully(src);
\r
218 if (memory != null)
\r
223 public void writeFully(ByteBuffer src, int length) throws IOException {
224 backend.writeFully(src, length);
\r
225 if (memory != null)
\r
230 public void write(byte[] src, int offset, int length) throws IOException {
231 backend.write(src, offset, length);
\r
235 public void write(byte[] src) throws IOException {
236 backend.write(src);
\r
237 if (memory != null)
\r
242 public void writeDouble(double value) throws IOException {
243 backend.writeDouble(value);
\r
244 if (memory != null)
\r
249 public void writeFloat(float value) throws IOException {
250 backend.writeFloat(value);
\r
251 if (memory != null)
\r
256 public void writeInt(int value) throws IOException {
257 backend.writeInt(value);
\r
258 if (memory != null)
\r
263 public void writeLong(long value) throws IOException {
264 backend.writeLong(value);
\r
265 if (memory != null)
\r
270 public void writeShort(int value) throws IOException {
271 backend.writeShort(value);
\r
272 if (memory != null)
\r
277 public void writeChar(int value) throws IOException {
\r
278 backend.writeChar(value);
\r
279 if (memory != null)
\r
284 public void writeBytes(String s) throws IOException {
\r
285 backend.writeBytes(s);
\r
286 if (memory != null)
\r
291 public void writeChars(String s) throws IOException {
\r
292 backend.writeChars(s);
\r
293 if (memory != null)
\r
298 public void writeUTF(String s) throws IOException {
\r
299 backend.writeUTF(s);
\r
300 if (memory != null)
\r
305 public void insertBytes(long bytes, ByteSide side) throws IOException {
306 throw new UnsupportedOperationException();
\r
310 public void removeBytes(long bytes, ByteSide side) throws IOException {
311 throw new UnsupportedOperationException();
\r
315 public long length() throws IOException {
316 return backend.length();
320 public void setLength(long newLength) throws IOException {
\r
321 throw new UnsupportedOperationException();
325 public String toString() {
327 return "DeferredBinaryFile(file="+file.getName()+", size="+length()+")";
328 } catch (IOException e) {
329 return "DeferredBinaryFile()";
333 private void threshold() throws IOException {
\r
334 if (backend.position() >= threshold) {
\r
335 backend = new BinaryFile(file, fileBufferSize);
\r
336 long length = memory.position();
\r
337 memory.position(0);
\r
338 memory.toByteBuffer().position(0);
\r
339 backend.writeFully(memory.toByteBuffer(), (int) length);
\r
344 public boolean isInMemory() {
\r
345 return memory != null;
\r
348 public RandomAccessBinary getMemory() {
\r
352 public RandomAccessBinary getBackend() {
\r