注意,除了mcfinnigan的回答,在使用代码的时候一定要知道:
FileOutputStream fos = new FileOutputStream(f); // create a file output stream around f
ftpClient.retrieveFile("/" + ftpFile.getName(), fos);
然后将在第一行的文件系统上创建一个空文件。然后,如果第二行抛出异常,因为 path 不存在远程文件"/" + ftpFile.getName()
,空文件仍将在您的文件系统上。
所以我用 Guava 做了一点 LazyInitOutputStream 来处理这个问题:
public class LazyInitOutputStream extends OutputStream {
private final Supplier<OutputStream> lazyInitOutputStreamSupplier;
public LazyInitOutputStream(Supplier<OutputStream> outputStreamSupplier) {
this.lazyInitOutputStreamSupplier = Suppliers.memoize(outputStreamSupplier);
}
@Override
public void write(int b) throws IOException {
lazyInitOutputStreamSupplier.get().write(b);
}
@Override
public void write(byte b[]) throws IOException {
lazyInitOutputStreamSupplier.get().write(b);
}
@Override
public void write(byte b[], int off, int len) throws IOException {
lazyInitOutputStreamSupplier.get().write(b,off,len);
}
public static LazyInitOutputStream lazyFileOutputStream(final File file) {
return lazyFileOutputStream(file,false);
}
public static LazyInitOutputStream lazyFileOutputStream(final File file,final boolean append) {
return new LazyInitOutputStream(new Supplier<OutputStream>() {
@Override
public OutputStream get() {
try {
return new FileOutputStream(file,append);
} catch (FileNotFoundException e) {
throw Throwables.propagate(e);
}
}
});
}
我在使用带有 FTP/SFTP 文件下载功能的 Spring 集成 remote.file 包时遇到了这个问题。我用它来解决这个空文件问题:
try ( OutputStream downloadedFileStream = LazyInitOutputStream.lazyFileOutputStream(destinationfilePath.toFile()) ) {
remoteFileSession.read(source, downloadedFileStream);
}