]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/FileIO.java
Fixing problems in the database unit testing environment with Acorn
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / FileIO.java
1 package org.simantics.acorn;
2
3 import java.io.BufferedOutputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.io.RandomAccessFile;
7 import java.nio.ByteBuffer;
8 import java.nio.channels.FileChannel;
9 import java.nio.channels.SeekableByteChannel;
10 import java.nio.file.Files;
11 import java.nio.file.OpenOption;
12 import java.nio.file.Path;
13 import java.nio.file.Paths;
14 import java.nio.file.StandardOpenOption;
15 import java.nio.file.attribute.FileAttribute;
16 import java.util.HashSet;
17 import java.util.Set;
18
19 import org.simantics.databoard.file.RuntimeIOException;
20
21 public class FileIO {
22
23     private static final FileAttribute<?>[] NO_ATTRIBUTES = {};
24
25     private static final Set<OpenOption> CREATE_OPTIONS = new HashSet<>(2);
26     private static final Set<OpenOption> APPEND_OPTIONS = new HashSet<>(1);
27
28     static {
29         CREATE_OPTIONS.add(StandardOpenOption.WRITE);
30         CREATE_OPTIONS.add(StandardOpenOption.CREATE);
31
32         APPEND_OPTIONS.add(StandardOpenOption.APPEND);
33     }
34
35         private Path path;
36         private int writePosition = 0;
37
38         public FileIO(Path path) {
39                 this.path = path;
40         }
41
42         //private static final boolean TRACE_SWAP = false;
43         private static final boolean TRACE_PERF = false;
44
45         public synchronized int saveBytes(byte[] bytes, int length, boolean overwrite) throws IOException {
46                 if(overwrite) writePosition = 0;
47                 int result = writePosition;
48                 long start = System.nanoTime();
49                 Set<OpenOption> options = writePosition == 0 ? CREATE_OPTIONS : APPEND_OPTIONS;
50                 
51                 ByteBuffer bb = ByteBuffer.wrap(bytes, 0, length);
52                 try (FileChannel fc = FileChannel.open(path, options, NO_ATTRIBUTES)) {
53             fc.write(bb);
54             
55             writePosition += length;
56             if(TRACE_PERF) {
57                 long duration = System.nanoTime()-start;
58                 double ds = 1e-9*duration;
59                 System.err.println("Wrote " + bytes.length + " bytes @ " + 1e-6*bytes.length / ds + "MB/s");
60             }
61             return result;
62                 } catch (Throwable t) {
63                     throw new IOException("An error occured file saving bytes for file " + path.toAbsolutePath().toString(), t);
64                 }
65         }
66
67     public synchronized byte[] readBytes(int offset, int length) throws IOException {
68         long start = System.nanoTime();
69         try (SeekableByteChannel channel = Files.newByteChannel(path)) {
70             channel.position(offset);
71             ByteBuffer buf = ByteBuffer.allocate(length);
72             int read = 0;
73             while (read < length) {
74                 read += channel.read(buf);
75             }
76             byte[] result = buf.array();
77             if (result.length != length)
78                 System.err.println("faa");
79             if (TRACE_PERF) {
80                 long duration = System.nanoTime() - start;
81                 double ds = 1e-9 * duration;
82                 System.err.println("Read " + result.length + " bytes @ " + 1e-6 * result.length / ds + "MB/s");
83             }
84             return result;
85         }
86     }
87
88         public static void syncPath(Path f) throws IOException {
89                 // Does not seem to need 's' according to unit test in Windows
90                 try (RandomAccessFile raf = new RandomAccessFile(f.toFile(), "rw")) {
91                         raf.getFD().sync();
92                 }
93         }
94
95         static void uncheckedSyncPath(Path f) {
96                 try {
97                         syncPath(f);
98                 } catch (IOException e) {
99                         throw new RuntimeIOException(e);
100                 }
101         }
102
103         public static void main(String[] args) throws Exception {
104
105                 byte[] buf = new byte[1024*1024];
106                 
107                 long s = System.nanoTime();
108                 
109                 Path test = Paths.get("e:/work/test.dat");
110                 OutputStream fs = Files.newOutputStream(test);
111                 OutputStream os = new BufferedOutputStream(fs, 128*1024);
112                 
113                 for(int i=0;i<40;i++) {
114                         os.write(buf);
115                 }
116                 
117                 os.flush();
118                 //fs.getFD().sync();
119                 os.close();
120                 
121                 syncPath(test);
122                 
123                 long duration = System.nanoTime()-s;
124                 System.err.println("Took " + 1e-6*duration + "ms.");
125                 
126                 
127         }
128         
129 }