gpt4 book ai didi

java - 如何使用 FileChannels transferFrom() 方法监控进度(JProgressBar)?

转载 作者:太空狗 更新时间:2023-10-29 23:01:19 41 4
gpt4 key购买 nike

我需要一些关于 JProgressBar 组件的帮助。我的程序使用 java.nio FileChannels 将文件从一个地方复制到另一个地方。实际的复制方法是transferFrom()

我现在有两个问题。

  1. 如何监控 FileChannels 的传输进度?我发现的所有教程都使用传统的 java.io InputStreams 并在循环输入流时增加 progress int。

  2. 我的复制方法(FileChannel 方法)被封装在一个单独的方法中,该方法由循环遍历源文件夹和目标文件夹的其他方法调用,然后为每个文件调用 FileChannel 方法。

如何为完整的复制机制实现 ProgressBar?

好吧,我应该早点阅读常见问题解答,所以我想我必须编辑我的初始帖子而不是评论答案,对吧?

好的,这就是我到目前为止所做的。正如 jambjo 所建议的(顺便感谢),transferFrom() 方法现在是循环的。顺便说一句:是否有更好的 block 大小,或者它是否像 EJP 所说的那样取决于我的进度条的粒度?

这是我的代码片段:

while (position < size) {
position += destination.transferFrom(source, position, chunkSize);
current = (position/size)*100;
System.out.println(current);
}

不幸的是,“当前”值在循环中保持为 0,我不知道为什么。我错过了什么吗?

再次感谢 jambjo!非常感谢您的意见!现在单个文件的进度监控可以工作了,让我们来解决我的第二个问题。


我希望(不,我必须)不仅要监视单个文件的进度,还要监视一堆文件的进度。我的主要复制方法遍历各种目录并通过调用实际的传输方法复制适当的文件。所以复制方法不传输文件,它们只是为实际的传输方法选择文件。

最佳答案

我意识到我在这里复活了一个非常古老的线程,但我今天在谷歌搜索中遇到了它,所以......

如果您想监控进度,最好按照 EJP 建议让系统处理 block 大小,以便优化传输。监视的方法是为 ReadableByteChannel 编写一个包装类,每当调用其 read 方法时,您都可以使用它来传递进度消息。这是一个例子:

package download.progress.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class DownloadProgressExample {
public static void main( String[] args ) {
new Downloader( "/tmp/foo.mp3", "http://example.com/bar.mp3" );
}

private interface RBCWrapperDelegate {
// The RBCWrapperDelegate receives rbcProgressCallback() messages
// from the read loop. It is passed the progress as a percentage
// if known, or -1.0 to indicate indeterminate progress.
//
// This callback hangs the read loop so a smart implementation will
// spend the least amount of time possible here before returning.
//
// One possible implementation is to push the progress message
// atomically onto a queue managed by a secondary thread then
// wake that thread up. The queue manager thread then updates
// the user interface progress bar. This lets the read loop
// continue as fast as possible.
public void rbcProgressCallback( RBCWrapper rbc, double progress );
}

private static final class Downloader implements RBCWrapperDelegate {
public Downloader( String localPath, String remoteURL ) {
FileOutputStream fos;
ReadableByteChannel rbc;
URL url;

try {
url = new URL( remoteURL );
rbc = new RBCWrapper( Channels.newChannel( url.openStream() ), contentLength( url ), this );
fos = new FileOutputStream( localPath );
fos.getChannel().transferFrom( rbc, 0, Long.MAX_VALUE );
} catch ( Exception e ) {
System.err.println( "Uh oh: " + e.getMessage() );
}
}

public void rbcProgressCallback( RBCWrapper rbc, double progress ) {
System.out.println( String.format( "download progress %d bytes received, %.02f%%", rbc.getReadSoFar(), progress ) );
}

private int contentLength( URL url ) {
HttpURLConnection connection;
int contentLength = -1;

try {
HttpURLConnection.setFollowRedirects( false );

connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod( "HEAD" );

contentLength = connection.getContentLength();
} catch ( Exception e ) { }

return contentLength;
}
}

private static final class RBCWrapper implements ReadableByteChannel {
private RBCWrapperDelegate delegate;
private long expectedSize;
private ReadableByteChannel rbc;
private long readSoFar;

RBCWrapper( ReadableByteChannel rbc, long expectedSize, RBCWrapperDelegate delegate ) {
this.delegate = delegate;
this.expectedSize = expectedSize;
this.rbc = rbc;
}

public void close() throws IOException { rbc.close(); }
public long getReadSoFar() { return readSoFar; }
public boolean isOpen() { return rbc.isOpen(); }

public int read( ByteBuffer bb ) throws IOException {
int n;
double progress;

if ( ( n = rbc.read( bb ) ) > 0 ) {
readSoFar += n;
progress = expectedSize > 0 ? (double) readSoFar / (double) expectedSize * 100.0 : -1.0;
delegate.rbcProgressCallback( this, progress );
}

return n;
}
}
}

关于java - 如何使用 FileChannels transferFrom() 方法监控进度(JProgressBar)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2263062/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com