有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中获取FTP连接上的Zip文件大小

我正在通过FTP连接发送zip文件,因此为了获取文件大小,我使用了:

URLConnection conn = imageURL.openConnection();
long l = conn.getContentLengthLong();

但它返回-1

同样,对于通过Http请求发送的文件,我得到了正确的文件大小

在这种情况下,如何在ftp连接中获得正确的文件大小


共 (1) 个答案

  1. # 1 楼答案

    for files sent over Http request , I get correct file size.

    也许吧URLConnection.getContentLength[Long]专门返回内容长度标题。HTTP(和HTTPS)支持几种不同的主体划分方式,根据服务器实现的HTTP选项和版本,它可能使用内容长度头,也可能不使用

    类似地,FTP服务器可以在操作开始时提供“检索”文件的大小,也可以不提供。但它从不使用内容长度的头来执行此操作,所以getContentLength[Long]无法获得它。然而,如果服务器提供了实现代码,则实现代码会在内部存储它,并且可以通过以下非常丑陋的黑客攻击来提取它:

        URL url = new URL ("ftp://anonymous:dummy@192.168.56.2/pub/test"); 
        URLConnection conn = url.openConnection();
        try( InputStream is = conn.getInputStream() ){
            if( ! conn.getClass().getName().equals("sun.net.www.protocol.ftp.FtpURLConnection") ) throw new Exception("conn wrong");
            Field fld1 = conn.getClass().getDeclaredField("ftp"); 
            fld1.setAccessible(true); Object ftp = fld1.get(conn);
            if( ! ftp.getClass().getName().equals("sun.net.ftp.impl.FtpClient") ) throw new Exception ("ftp wrong");
            Field fld2 = ftp.getClass().getDeclaredField("lastTransSize");
            fld2.setAccessible(true); long size = fld2.getLong(ftp);
            System.out.println (size);
        }
    

    黑客攻击未记录的内部文件可能会在任何时候失败,8以上的Java版本会逐渐阻止它:9到15会发出关于非法访问的警告消息,除非您使用 add-opens来允许它,并且16会使它成为错误(即致命的)。除非你真的在读取数据之前需要大小(这隐含地给了你大小),否则我不建议这样做