简体   繁体   中英

create File from FileOutputStream

I'm using org.apache.commons.net.ftp to download files in a remote machine. There is a method, that reads the files to a FileOutputStream object.

ftpClient.retrieveFile("/" + ftpFile.getName(), fos);

Problem, here is, i've another method that accepts a File object. So, i need to create a File object file the FileOutputStream . I think, i need to create an InputStream to be able to create a file object from the FileOutputStream . is this correct? I might be missing something and there should be an easy way to create a File from a FileOutputStream ?

FileOutputStream has a constructor that takes a File object.

The following should do what you need it to do:

File f = new File("path/to/my/file");
if(f.createNewFile()) { // may not be necessary
    FileOutputStream fos = new FileOutputStream(f); // create a file output stream around f
    ftpClient.retrieveFile("/" + ftpFile.getName(), fos);

    otherMethod(f); // pass the file to your other method
}

Note that in addition to the answer of mcfinnigan, you must know that when you use the code:

FileOutputStream fos = new FileOutputStream(f); // create a file output stream around f
ftpClient.retrieveFile("/" + ftpFile.getName(), fos);

Then an empty file will be created on your filesystem on the first line. Then if the 2nd line throws an exception, because no remote file exist for path "/" + ftpFile.getName() , the empty file will still be on your filesystem.

So I've done a little LazyInitOutputStream with Guava to handle that:

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);
        }
      }
    });
  }

I've encoutered this problem while using Spring integration remote.file packages, with the FTP/SFTP file download features. I use it like that to solve this empty file problem:

try ( OutputStream downloadedFileStream = LazyInitOutputStream.lazyFileOutputStream(destinationfilePath.toFile()) ) {
  remoteFileSession.read(source, downloadedFileStream);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM