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