我有一个简单的解决方案,但不是 100% 准确,您可以通过增加采样率来改进它。现在我只使用一个示例 (TotalFileSize-CurrentByteTransferred/(CurrentTime-StartTime))。您可以添加更多采样以改善结果。以下是代码示例:
在此处更新上传统计信息
private final UploadStats uploadStats = new UploadStats();
private void updateUploadStats(long totalBytesTransferred, int bytesTransferred, long streamSize) {
long current = System.currentTimeMillis();
synchronized (this.uploadStats) {
long timeTaken = (current - uploadStats.getStartTime());
if (timeTaken > 1000L) {
uploadStats.setLastUpdated(current);
uploadStats.setEstimatedSpeed(totalBytesTransferred / (timeTaken/1000L));
}
uploadStats.setTotalBytesTransferred(totalBytesTransferred);
uploadStats.setBytesTransferred(bytesTransferred);
uploadStats.setStreamSize(streamSize);
}
}
创建 CopyStreamListener 并附加到 FTPClient
CopyStreamAdapter copyStreamAdapter = new CopyStreamAdapter() {
@Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
updateUploadStats(totalBytesTransferred, bytesTransferred, streamSize);
}
};
FTPClient ftpClient = new FTPClient();
ftpClient.connect(url);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
ftpClient.disconnect();
throw new Exception("Unable to connect.");
}
if (!ftpClient.login(username, password)) {
ftpClient.disconnect();
throw new Exception("Failed to login.");
}
ftpClient.setCopyStreamListener(copyStreamListener);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
ftpClient.storeFile(targetPath, inputFile);
ftpClient.logout();
ftpClient.disconnect();
在没有 getter/setter 的情况下上传 Stats bean。有些无关紧要,可以跳过
public class UploadStats {
private long totalBytesTransferred;
private int bytesTransferred;
private long streamSize;
private long lastUpdated;
private double estimatedSpeed;
private long startTime;
private long totalSize; }
这只是一个伪代码。如果您打算阅读和显示进度,则可以使用线程进行改进,因此 syncronized 关键字。