我试图弄清楚当我们使用nio FileChannel与普通FileInputStream/FileOuputStream文件读取和写入文件系统时,性能(或优势)是否有任何差异.我观察到,在我的机器上,两者都在同一级别执行,也很多次FileChannel都是慢一些.我可以了解比较这两种方法的更多细节.这是我使用的代码,我正在测试的文件是350MB.如果我不是在查看随机访问或其他此类高级功能,那么对文件I/O使用基于NIO的类是一个不错的选择吗?
package trialjavaprograms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class JavaNIOTest {
public static void main(String[] args) throws Exception {
useNormalIO();
useFileChannel();
}
private static void useNormalIO() throws Exception {
File file = new File("/home/developer/test.iso");
File oFile = new File("/home/developer/test2");
long time1 = System.currentTimeMillis();
InputStream is = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(oFile);
byte[] buf = new byte[64 * 1024];
int len = 0; …Run Code Online (Sandbox Code Playgroud) 我正在写一个STL文件,它由一个80字节的头,一个4字节的整数组成,然后是50个字节的记录,每个字节由浮点数和一个短整数组成.
使用RandomAccessFile我可以轻松地写入数据,但速度非常慢.它使用与DataOutputStream相同的接口.如果有一种简单的方法来缓冲数据输出流,我可以使用它,但烦人的部分是需要写出所有记录,并在最后计算三角形输出的数量,并将该整数写入字节81- 84.
直截了当但缓慢的方式,只关注大部分工作,即写下每个方面:
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);
}
Run Code Online (Sandbox Code Playgroud)
是否有任何优雅的方法将这种二进制数据写入块状快速I/O类?
在我看来,STL文件格式应该首先是低字节,Java可能是高字节优先.所以也许我的所有writeFloats都是徒劳的,我必须找到一个手动转换,以便它以小端形式出现?
如果必须,我愿意关闭文件,最后在randomaccessfile中重新打开,寻找字节81并写入计数.
因此,此编辑是对应该起作用的问题的两个答案的回应.第一个是添加BufferedWriter.结果非常快.我知道这台笔记本电脑是高端的SSD,但我并不期待这种性能,更不用说来自Java了.只需缓冲输出,在0.5秒内写入96Mb文件,在1.5秒内写入196Mb.
为了了解nio是否会提供更高的性能,我试图通过@ sturcotte06实现解决方案.代码不会尝试写标题,我只关注每个三角形的50字节记录.
public static void writeBinarySTL2(Shape3d s, String filename) {
java.nio.file.Path filePath = Paths.get(filename);
// Open a channel in write mode on your file.
try (WritableByteChannel channel = Files.newByteChannel(filePath, StandardOpenOption.CREATE)) {
// Allocate a new buffer.
ByteBuffer buf = ByteBuffer.allocate(50 * 1024);
ArrayList<Triangle> triangles = s.triangles;
// Write …Run Code Online (Sandbox Code Playgroud)