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