如何使用Apache FTPClient

时间:2015-05-16 13:12:54

标签: java android ftp

我正在使用Apache FTPClient在Android设备和某些FTP服务器之间下载/上传文件。 我想以Mbps / KBps来衡量下载和上传速度。

上传,我的代码看起来像这样:

// myFile is a path for local file inside my android device.
InputStream inputStream = new FileInputStream(myFile);
OutputStream outputStream = ftpclient.storeFileStream(remoteFile);

byte[] bytesIn = new byte[4096];
int read = 0;

while((read = inputStream.read(bytesIn)) != -1) {
    outputStream.write(bytesIn, 0, read);
}

inputStream.close();
outputStream.close();

对我来说,了解两件事非常重要:

  1. 为了下载,我所做的是总结我在while循环中读取的字节数(使用inputStream.read(serverFile)返回值) 好吗?它会反映下载速度吗?
  2. 要上传,如何正确测量文件的上传速度?这个FTP客户端怎么做? 据我所知,outputStream.write()没有返回有用的值.. 我的想法是在每次迭代后检查(写入)FTP服务器中文件的更新大小是什么,但我不知道这是否是正确/最简单的方法。以及如何使用此FTP客户端实现它。

1 个答案:

答案 0 :(得分:0)

我有一个简单的解决方案,但不是100%准确,你可以通过增加更多的采样率来改善它。现在我只使用一个样本,( TotalFileSize - CurrentByteTransferred /( CurrentTime - StartTime ))。您可以添加更多采样以改善结果。以下是代码示例:

在此更新上传统计信息

$ mono --version
Mono JIT compiler version 4.2.0 (Stable 4.2.0.179/a224653 Tue Oct  6 11:28:25 PDT 2015)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:           normal
    SIGSEGV:       altstack
    Notification:  kqueue
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug
    LLVM:          supported, not enabled.
    GC:            sgen

创建CopyStreamListener并附加到FTPClient

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

上传没有getter / setter的Stats bean。有些是不相关的,可以跳过

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

这只是一个伪代码。如果您打算阅读并显示进度,则可以使用线程进行改进,因此同步关键字。