我在java程序中遇到过I / O问题。我的程序在Linux下使用Java 7和Tomcat 7。线程1创建一个对象并使用JAXB将其序列化为文件:
public static void export1(JAXBContext context, Object object, Path filePath){
try {
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.marshal(object, filePath.toFile());
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
然后向外部实体发送通知。处理传入请求的线程遇到:
Caused by: java.nio.file.NoSuchFileException: PATH_TO_FILE
at sun.nio.fs.UnixException.translateToIOException(Unknown Source)
at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(Unknown Source)
at java.nio.file.Files.newByteChannel(Unknown Source)
at java.nio.file.Files.newByteChannel(Unknown Source)
我已阅读一些关于I/O concept flush vs sync的帖子,但我仍感到困惑。将我的代码重构为使用无缓冲输出流的下一个代码解决我的问题吗?
public static void export2(JAXBContext context, Object object, Path filePath){
try (OutputStream os = Files.newOutputStream(filePath)) {
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.marshal(object, os);
} catch (JAXBException | IOException e) {
throw new RuntimeException(e);
}
}
或者我应该直接使用文件描述符来同步OS缓冲区与底层设备吗?
public static void export3(JAXBContext context, Object object, Path filePath) {
try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.marshal(object, fos);
fos.getFD().sync();
} catch (JAXBException | IOException e) {
throw new RuntimeException(e);
}
}