【问题标题】:Getting FileSize before InputStream在 InputStream 之前获取 FileSize
【发布时间】:2010-08-12 00:46:39
【问题描述】:

我想为 FTP 下载创建一个进度条。我下载文件的服务器隐藏了它的所有目录和文件。我想显示下载进度。有什么办法可以获取文件大小吗?这是我当前的代码:

   FTPclient = new FTPClient();
               FTPclient.setListHiddenFiles(true);
               FTPclient.connect(hostPart);
               FTPclient.login(userName, passWord);
               FTPclient.setFileType(FTP.BINARY_FILE_TYPE);

                InputStream instream = FTPclient.retrieveFileStream(pathExcludingHostIncludingFirstSlash);


            int l;
            byte[] tmp = new byte[2048];
            int updateCounter = 0;
            int bytesDownloaded = 0;
            while ((l = instream.read(tmp)) != -1) {
                fos.write(tmp, 0, l);
                bytesDownloaded+=2048;
                updateCounter++;
                if(updateCounter==3){
                    kilobytesDownloaded=(bytesDownloaded / 1024);
                    publishProgress((String[])null);
                    updateCounter=0;
                }

【问题讨论】:

  • 您的代码假定每次读取都是 2048 字节。这不能保证,除非您保证您的文件甚至是 2048 字节的倍数,否则最终读取几乎肯定不会是这样。我会推荐bytesDownloaded += l

标签: java android ftp download progress-bar


【解决方案1】:

无法在所有 FTP 服务中可靠地执行此操作。

FTP 协议不提供获取文件大小的方法,因此您需要求助于请求目录列表并取消选择您返回的(特定于服务器的)文本。此外,不保证会启用目录列表,或者您将有权列出目录。

话虽如此,一些 FTP 库可以配置为尝试获取文件大小。例如,使用 Apache FTPClient 库,您可以(尝试)使用 listFiles(String) 方法并查看生成的 FTPFile 对象。

编辑

@Kevin Brock 提到 FTP SIZE 命令是一种可能性。

  • 这是 2007 年首次在 RFC 3659 中定义的命令。许多部署的 FTP 服务器软件比这要旧得多。
  • SIZE 是可选命令;即,即使符合 RFC 3659 的服务器也不需要支持它。
  • 即使服务器支持 SIZE,当前的 Apache FTPClient API 也不包含获取文件大小的方法(通过listFiles 除外)。当然,这在未来可能会改变。
  • ftp4j FTPClient 类显然确实实现了 SIZE 并通过其 fileSize(...) 方法使其可用。

【讨论】:

  • FTP 协议确实有“SIZE”命令 (nsftools.com/tips/RawFTP.htm#SIZE) 应该提供这个。您是说这不是通常实现的,还是 Java 客户端不允许您访问它?
  • 什么时候我必须将文件路径传递给 listFiles?我认为所有文件都被隐藏了。
  • @Aymon - 那你就有问题了。
【解决方案2】:

我也没有找到一个简单的命令来执行此操作。我的解决方案是调用跳过命令,应该返回跳过的字节数。将其相加,直到 skip 返回 0。skip 有可能由于文件结尾以外的原因返回 0,但在该字段中它似乎运行良好。

下面是一些示例代码:

InputStream checkStream = m_ftpClient.retrieveFileStream(name);

long fileLength = 0;
long transferredLength = 0;
do
{
    transferredLength = checkStream.skip(MAX_BYTES);
    fileLength += transferredLength;
}while(transferredLength > 0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2021-08-13
    • 2017-07-24
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多