I am writing an STL file consisting of an 80 byte header, 4 byte integer, and then a record of 50 bytes, each of which consists of floats and a short integer.
Using RandomAccessFile, I can easily write data, but it's terribly slow. This uses the same interface as the DataOutputStream. If there is a simple way to buffer the data output stream, I could use it, but the annoying part is the need to write out all the records, and at the end to count the number of triangles, output and write this integer in bytes 81-84.
A simple but slow way, just focusing on most of the work that writes every aspect:
public static void writeBinarySTL(Triangle t, RandomAccessFile d) throws IOException {
d.writeFloat((float)t.normal.x);
d.writeFloat((float)t.normal.y);
d.writeFloat((float)t.normal.z);
d.writeFloat((float)t.p1.x);
d.writeFloat((float)t.p1.y);
d.writeFloat((float)t.p1.z);
d.writeFloat((float)t.p2.x);
d.writeFloat((float)t.p2.y);
d.writeFloat((float)t.p2.z);
d.writeFloat((float)t.p3.x);
d.writeFloat((float)t.p3.y);
d.writeFloat((float)t.p3.z);
d.writeShort(0);
}
- , /?
, STL , Java, , . , , , , little-endian?
, , randomaccess, 81 .
, , . - BufferedWriter. - . , SSD, , Java. , 96 , 0,5 , 196 1,5 .
, nio , @sturcotte06. , 50 .
public static void writeBinarySTL2(Shape3d s, String filename) {
java.nio.file.Path filePath = Paths.get(filename);
try (WritableByteChannel channel = Files.newByteChannel(filePath, StandardOpenOption.CREATE)) {
ByteBuffer buf = ByteBuffer.allocate(50 * 1024);
ArrayList<Triangle> triangles = s.triangles;
for (int i = 0; i < triangles.size(); i += 1024) {
for (int j = i; j < i + 1024; ++j)
writeBinarySTL(triangles.get(j), buf);
buf.flip();
channel.write(buf);
}
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
WRITE (, , ), CREATE, , , .
Sphere902_bin2.stl
java.nio.file.NoSuchFileException: Sphere902_bin2.stl
sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
at
sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at
sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at
sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) java.nio.file.Files.newByteChannel(Files.java:361) java.nio.file.Files.newByteChannel(Files.java:407) at edu.stevens.scad.STL.writeBinarySTL2 (STL.java:105)
, , , , , :
public static void writeBinarySTL(Triangle t, ByteBuffer buf) {
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.normal.x)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.normal.y)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.normal.y)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p1.x)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p1.y)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p1.z)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p2.x)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p2.y)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p2.z)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p3.x)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p3.y)));
buf.putInt(Integer.reverseBytes(Float.floatToIntBits((float)t.p3.z)));
buf.putShort((short)0);
}
MWE, , :
package language;
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.nio.channels.*;
public class FastWritenio {
public static void writeUsingPrintWriter() throws IOException {
PrintWriter pw = new PrintWriter(new FileWriter("test.txt"));
pw.print("testing");
pw.close();
}
public static void writeUsingnio(int numTrials, int bufferSize, int putsPer) throws IOException {
String filename = "d:/test.dat";
java.nio.file.Path filePath = Paths.get(filename);
WritableByteChannel channel = Files.newByteChannel(filePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ);
ByteBuffer buf = ByteBuffer.allocate(bufferSize);
for (int t = 0; t < numTrials; ++t) {
for (int i = 0; i < putsPer; i ++) {
buf.putInt(i);
}
buf.flip();
channel.write(buf);
}
channel.close();
}
public static void main(String[] args) throws IOException {
writeUsingPrintWriter();
long t0 = System.nanoTime();
writeUsingnio(1024*256, 8*1024, 2048);
System.out.println((System.nanoTime()-t0)*1e-9);
}
}