1 package org.simantics.db.common.utils;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.nio.ByteBuffer;
10 import java.nio.channels.FileChannel;
11 import java.util.Arrays;
13 import org.simantics.databoard.Bindings;
14 import org.simantics.databoard.Files;
15 import org.simantics.databoard.binding.Binding;
16 import org.simantics.databoard.serialization.Serializer;
17 import org.simantics.databoard.type.Datatype;
18 import org.simantics.databoard.util.binary.RandomAccessBinary;
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.Resource;
21 import org.simantics.db.WriteGraph;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.layer0.Layer0;
26 * Converts byte[] literals to files and back. These utilities are not usable
27 * for literals of any other type than byte[].
29 public class LiteralFileUtil {
31 public static void copyByteArrayToFile(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
32 byte[] data = g.getValue(source, Bindings.BYTE_ARRAY);
33 OutputStream stream = new FileOutputStream(target);
35 // TODO: For some peculiar reason a direct stream.write(data) OOMs with approx. 70MB array
36 for(int pos = 0;pos < data.length;) {
37 int len = Math.min(65536, data.length-pos);
38 stream.write(data,pos,len);
46 public static void copyByteArrayToFile(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
47 Resource source = g.getSingleObject(subject, predicate);
48 copyByteArrayToFile(g, source, target);
51 public static void copyRandomAccessBinaryToFile(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
52 OutputStream stream = new FileOutputStream(target);
54 RandomAccessBinary rab = g.getRandomAccessBinary(source);
55 // Skip byte array length data according to databoard byte[] serialization rules.
57 ByteBuffer bb = ByteBuffer.wrap(new byte[65536]);
58 byte[] bbArray = bb.array();
59 while (rab.position() < rab.length()) {
60 rab.readFully(bb, (int) Math.min(bbArray.length, rab.length() - rab.position()));
61 stream.write(bbArray, 0, bb.position());
69 public static void copyRandomAccessBinaryFromFile(File source, RandomAccessBinary rab) throws IOException {
70 ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[65536]);
72 FileInputStream stream = new FileInputStream(source);
73 FileChannel channel = stream.getChannel();
77 rab.writeInt((int)source.length());
78 while(channel.read(byteBuffer) != -1) {
79 byteBuffer.limit(byteBuffer.position());
80 byteBuffer.position(0);
81 rab.writeFully(byteBuffer);
82 byteBuffer.position(0);
88 // Make sure the RAB file will not be longer than the
89 // source file due to possible previously existing data.
90 rab.setLength(rab.position());
95 public static void copyRandomAccessBinaryToFile(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
96 Resource source = g.getSingleObject(subject, predicate);
97 copyRandomAccessBinaryToFile(g, source, target);
100 public static void copyToFileWithBinding(ReadGraph g, Resource source, File target, Binding binding) throws DatabaseException, IOException {
101 // Datatyyppi tieto on jo resurssissa, eik�?
102 // Sidonnan saisi Bindings.getBinding( type )
103 Object value = g.getValue(source, binding);
104 Serializer s = Bindings.getSerializerUnchecked(binding);
105 s.serialize(value, target);
108 public static void copyToFileWithBinding(ReadGraph g, Resource subject, Resource predicate, File target, Binding binding) throws DatabaseException, IOException {
109 Resource source = g.getSingleObject(subject, predicate);
110 copyToFileWithBinding(g, source, target, binding);
113 public static void copyToFileAsVariant(ReadGraph g, Resource source, File target, Binding binding) throws DatabaseException, IOException {
114 Object value = g.getValue(source, binding);
115 Files.createFile(target, binding, value);
118 public static void copyToFileAsVariant(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
119 Datatype type = g.getDataType(source);
120 Binding binding = Bindings.getBinding(type);
121 copyToFileAsVariant(g, source, target, binding);
124 public static void copyToFileAsVariant(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
125 Resource source = g.getSingleObject(subject, predicate);
126 copyToFileAsVariant(g, source, target);
129 public static void copyByteArrayFromFile(WriteGraph g, File source, Resource target) throws DatabaseException, IOException {
130 InputStream stream = new FileInputStream(source);
131 byte[] data = new byte[(int)source.length()];
134 g.claimValue(target, data, Bindings.BYTE_ARRAY);
137 public static void copyByteArrayFromFile(WriteGraph g, File source, Resource subject, Resource predicate) throws DatabaseException, IOException {
138 InputStream stream = new FileInputStream(source);
139 byte[] data = new byte[(int)source.length()];
142 g.claimLiteral(subject, predicate, data, Bindings.BYTE_ARRAY);
150 * @throws DatabaseException
151 * @throws IOException
153 public static void streamingCopyByteArrayFromFile(WriteGraph g, File source, Resource subject, Resource predicate) throws DatabaseException, IOException {
154 Resource target = g.getPossibleObject(subject, predicate);
155 if (target == null) {
156 Layer0 L0 = Layer0.getInstance(g);
157 target = g.newResource();
158 g.claim(target, L0.InstanceOf, null, L0.ByteArray);
159 g.claim(subject, predicate, target);
161 InputStream stream = new FileInputStream(source);
163 copyStreamToRandomAccessBinary(g, stream, target);
169 public static void copyByteArrayFromStream(WriteGraph g, InputStream source, Resource target) throws IOException, DatabaseException {
170 byte[] buffer = new byte[0x10000];
173 int count = source.read(buffer, pos, buffer.length - pos);
177 if(pos == buffer.length)
178 buffer = Arrays.copyOf(buffer, (pos * 3) / 2);
180 buffer = Arrays.copyOf(buffer, pos);
181 g.claimValue(target, buffer, Bindings.BYTE_ARRAY);
184 public static void copyStreamToRandomAccessBinary(WriteGraph g, InputStream source, Resource target) throws IOException, DatabaseException {
185 RandomAccessBinary rab = g.getRandomAccessBinary(target);
186 byte[] buffer = new byte[0x10000];
187 if (rab.length() < 4)
192 int count = source.read(buffer, 0, buffer.length);
195 rab.write(buffer, 0, count);
199 rab.writeInt(length);