Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Apache Commons VFS中监视文件传输的进度?_Java_Apache Commons_Vfs_Apache Commons Vfs - Fatal编程技术网

Java 如何在Apache Commons VFS中监视文件传输的进度?

Java 如何在Apache Commons VFS中监视文件传输的进度?,java,apache-commons,vfs,apache-commons-vfs,Java,Apache Commons,Vfs,Apache Commons Vfs,使用,如何监视文件传输的进度。我需要能够做到上传和下载。我还需要通过HTTP、FTP、SFTP和FTPS监控进度。我在文档中找不到任何关于它的信息。可以通过从VFS获取输入和输出流来完成。下面的示例使用commons net(VFS的依赖项)中的实用程序类来管理复制和进度监视。你同样可以手动完成 import org.apache.commons.net.io.Util; import org.apache.commons.net.io.CopyStreamListener; private

使用,如何监视文件传输的进度。我需要能够做到上传和下载。我还需要通过HTTP、FTP、SFTP和FTPS监控进度。我在文档中找不到任何关于它的信息。

可以通过从VFS获取输入和输出流来完成。下面的示例使用commons net(VFS的依赖项)中的实用程序类来管理复制和进度监视。你同样可以手动完成

import org.apache.commons.net.io.Util;
import org.apache.commons.net.io.CopyStreamListener;

private void copy(FileObject sourceFile, FileObject destinationFile, CopyStreamListener progressMonitor) throws IOException {
    InputStream sourceFileIn = sourceFile.getContent().getInputStream();
    try {
        OutputStream destinationFileOut = destinationFile.getContent().getOutputStream();
        try {
            Util.copyStream(sourceFileIn, destinationFileOut, Util.DEFAULT_COPY_BUFFER_SIZE, sourceFile.getContent().getSize(), progressMonitor);
        } finally {
            destinationFileOut.close();
        }
    } finally {
        sourceFileIn.close();
    }
}

提议的解决方案有点不合适,而且有点“弱”。让我们试试更整洁的吧
注意:以下代码需要JDK 16

给定使用标准启动的复制操作示例:

final var manager = VFS.getManager();
final var origin = manager.resolveFile(originUri.toString(), fileSystemOptions);
final var destination = manager.resolveFile(destinationUri.toString(), fileSystemOptions);
destination.copyFrom(origin, Selectors.SELECT_ALL);
只需将目标
FileObject
包装成一个自定义的委托实现,我们可以称之为
ProgressFileObject
,它也将接受一个
ProgressListener

final var listener = new ProgressListener() {
  @Override
  public void started() {
    System.out.println("Started");
  }

  @Override
  public void completed() {
    System.out.println("Completed");
  }

  @Override
  public void failed(@NotNull final Exception e) {
    System.out.println("Failed: " + e.getMessage());
  }

  @Override
  public void progress(@NotNull final ProgressEvent event) {
    final var out = "%d\t\t\t%d\t\t\tFile: %s".formatted(
        event.totalBytes(),
        event.totalTransferredBytes(),
        event.lastFileDestinationPath()
    );

    System.out.println(out);
  }
};

final var progressDestination = new ProgressFileObject(destination, listener);
progressFileObject.copyFrom(origin, Selectors.SELECT_ALL);
这将导致,带有一个文件夹:

Started
4648320         119391          File: /test_dir/AN/ANI0.evt
4648320         119511          File: /test_dir/AN/ANI0.hpj
4648320         119584          File: /test_dir/AN/ANI0.ipf
4648320         119585          File: /test_dir/AN/ANI0.ipm
4648320         1907060         File: /test_dir/AN/ANI0.LST
4648320         1907253         File: /test_dir/AN/ANI0.MRG
4648320         2472700         File: /test_dir/AN/ANI0.ODF
4648320         2472707         File: /test_dir/AN/ANI0.ph
4648320         2473421         File: /test_dir/AN/ANI0.rbj
4648320         2473547         File: /test_dir/AN/ANI0.rc
4648320         2473708         File: /test_dir/AN/ANI0.rst
4648320         2474813         File: /test_dir/AN/ANI0.rtf
4648320         2474814         File: /test_dir/AN/ANI0.txc
4648320         2474819         File: /test_dir/AN/ANI0.txm
4648320         2474820         File: /test_dir/AN/ANI0.vpf
4648320         2829348         File: /test_dir/AN/ANI0.VPG
4648320         2829466         File: /test_dir/AN/P0000001.rc
4648320         2829592         File: /test_dir/AN/P0000002.rc
4648320         4648275         File: /test_dir/AN/VPGSAV55.C2T
4648320         4648320         File: /test_dir/AN/VRPGWIN.RC
Completed
以下是
ProgressFileObject
ProgressListener
ProgressEvent
来源:

/**
 * @author Edoardo Luppi
 */
public class ProgressFileObject extends DecoratedFileObject {
  private final FileObject fileObject;
  private final ProgressListener listener;

  public ProgressFileObject(
      @NotNull final FileObject fileObject,
      @NotNull final ProgressListener listener) {
    super(fileObject);
    this.fileObject = fileObject;
    this.listener = listener;
  }

  @Override
  public void copyFrom(final FileObject file, final FileSelector selector) throws FileSystemException {
    if (!FileObjectUtils.exists(file)) {
      final var exception = new FileSystemException("vfs.provider/copy-missing-file.error", file);
      listener.failed(exception);
      throw exception;
    }

    listener.started();

    // Locate the files to copy across
    final List<FileObject> files = new ArrayList<>();
    file.findFiles(selector, false, files);

    // Calculate the total bytes that will be copied
    var totalBytes = 0L;

    for (final var srcFile : files) {
      if (srcFile.getType().hasContent()) {
        totalBytes += srcFile.getContent().getSize();
      }
    }

    var totalTransferredBytes = 0L;

    // Copy everything across
    for (final var srcFile : files) {
      // Determine the destination file
      final var relPath = file.getName().getRelativeName(srcFile.getName());
      final var destFile = resolveFile(relPath, NameScope.DESCENDENT_OR_SELF);

      // Clean up the destination file, if necessary
      if (FileObjectUtils.exists(destFile) && destFile.getType() != srcFile.getType()) {
        // The destination file exists, and is not of the same type, so delete it
        destFile.deleteAll();
      }

      // Copy across
      try {
        if (srcFile.getType().hasContent()) {
          try (final var content = srcFile.getContent()) {
            final var fileTransferredBytes = content.write(destFile);
            totalTransferredBytes += fileTransferredBytes;
            final var event = new ProgressEvent(
                totalBytes,
                totalTransferredBytes,
                fileTransferredBytes,
                srcFile.getName().getPath(),
                destFile.getName().getPath()
            );
        
            listener.progress(event);
          }
        } else if (srcFile.getType().hasChildren()) {
          destFile.createFolder();
        }
      } catch (final IOException e) {
        final var exception = new FileSystemException("vfs.provider/copy-file.error", e, srcFile, destFile);
        listener.failed(exception);
        throw exception;
      }
    }

    listener.completed();
  }

  @Override
  public URI getURI() {
    return fileObject.getURI();
  }

  @Override
  public Path getPath() {
    return fileObject.getPath();
  }

  @Override
  public boolean isSymbolicLink() throws FileSystemException {
    return fileObject.isSymbolicLink();
  }

  @Override
  public void forEach(final Consumer<? super FileObject> action) {
    fileObject.forEach(action);
  }

  @Override
  public Spliterator<FileObject> spliterator() {
    return fileObject.spliterator();
  }

  @Override
  public int hashCode() {
    return fileObject.hashCode();
  }

  @Override
  public boolean equals(final Object obj) {
    return fileObject.equals(obj);
  }

  @Override
  public String toString() {
    return fileObject.toString();
  }

  public interface ProgressListener {
    void started();
    void completed();
    void failed(@NotNull final Exception e);
    void progress(@NotNull final ProgressEvent event);
  }

  public record ProgressEvent(
      long totalBytes,
      long totalTransferredBytes,
      long lastFileTransferredBytes,
      String lastFileOriginPath,
      String lastFileDestinationPath
  ) {}
}
/**
*@作者Edoardo Luppi
*/
公共类ProgressFileObject扩展了DecoratedFileObject{
私有最终文件对象文件对象;
私人最终听众;
公共ProgressFileObject(
@NotNull最终文件对象文件对象,
@NotNull最终进程侦听器(侦听器){
超级(文件对象);
this.fileObject=fileObject;
this.listener=listener;
}
@凌驾
public void copyFrom(最终文件对象文件、最终文件选择器)引发FileSystemException{
如果(!FileObjectUtils.exists(file)){
final var exception=new FileSystemException(“vfs.provider/copy missing file.error”,file);
listener.failed(异常);
抛出异常;
}
listener.started();
//找到要复制的文件
最终列表文件=新的ArrayList();
findFiles(选择器,false,files);
//计算将要复制的总字节数
var totalBytes=0L;
用于(最终文件:文件){
if(srcFile.getType().hasContent()){
totalBytes+=srcFile.getContent().getSize();
}
}
var totalTransferredBytes=0L;
//把所有东西都抄过来
用于(最终文件:文件){
//确定目标文件
final var relPath=file.getName().getRelativeName(srcFile.getName());
final var destFile=resolveFile(relPath、NameScope.degent\u或SELF);
//如有必要,请清理目标文件
if(FileObjectUtils.exists(destFile)&&destFile.getType()!=srcFile.getType()){
//目标文件存在,并且不是同一类型,请删除它
destFile.deleteAll();
}
//抄袭
试一试{
if(srcFile.getType().hasContent()){
try(final var content=srcFile.getContent()){
final var fileTransferredBytes=content.write(destFile);
totalTransferredBytes+=文件TransferredBytes;
最终var事件=新ProgressEvent(
总字节数,
totalTransferredBytes,
fileTransferredBytes,
srcFile.getName().getPath(),
destFile.getName().getPath()
);
进程(事件);
}
}else if(srcFile.getType().hasChildren()){
destFile.createFolder();
}
}捕获(最终IOE例外){
final var exception=new FileSystemException(“vfs.provider/copy file.error”,e,srcFile,destFile);
listener.failed(异常);
抛出异常;
}
}
listener.completed();
}
@凌驾
公共URI getURI(){
返回fileObject.getURI();
}
@凌驾
公共路径getPath(){
返回fileObject.getPath();
}
@凌驾
公共布尔值isSymbolicLink()引发FileSystemException{
返回fileObject.isSymbolicLink();
}
@凌驾

public void forEach(最终用户)除了滚动您自己的监视器(如接受的答案中所述)Commons VFS中没有通用的进度回调基础设施(但可能应该有)。它已经被提到是一个TODO