• FTPClient上传文件大小为0字节但不报错的问题顺利解决


    今天通过FTPClient上传文件时出现,虽然无错误出现但是上传到服务器端的文件大小为0。

    如图:

     之前的代码:

    //FTP文件上传
        public static boolean upload(String hostname, int port, String username, String password,
                                     String targetPath, String fileName, InputStream inputStream) throws SocketException, IOException {
            //实例化ftpClient
            FTPClient ftpClient = new FTPClient();
    
            //设置登陆超时时间,默认是20s
            ftpClient.setDataTimeout(12000);
            //1.连接服务器
            ftpClient.connect(hostname, port);
            
            //2.登录(指定用户名和密码)
            boolean b = ftpClient.login(username, password);
            if (!b) {
                log.info("ftp登陸超時");
                if (ftpClient.isConnected()) {
                    // 断开连接
                    ftpClient.disconnect();
                }
            }
            log.info("ftp登陸成功");
            // 设置字符编码
            ftpClient.setControlEncoding("UTF-8");
            //基本路径,一定存在
            String[] pathArray = targetPath.split("/");
            for (String path : pathArray) {
                if (path.equals("")) {
                    continue;
                }
                //3.指定目录 返回布尔类型 true表示该目录存在
                boolean dirExsists = ftpClient.changeWorkingDirectory(path);
                //4.如果指定的目录不存在,则创建目录
                if (!dirExsists) {
                    //此方式,每次,只能创建一级目录
                    boolean flag = ftpClient.makeDirectory(path);
                    if (!flag) {
                        System.out.println("文件目录创建失败!");
                        return false;
                    }
                    ftpClient.changeWorkingDirectory(path);
                }
            }
            log.info("重新指定上传文件的路径:" + targetPath);
            //重新指定上传文件的路径
    //        ftpClient.changeWorkingDirectory(targetPath);
            //5.设置上传文件的方式
            ftpClient.setBufferSize(1024 * 1024 * 10);
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            /**
             * 6.执行上传
             * remote 上传服务后,文件的名称
             * local 文件输入流
             * 上传文件时,如果已经存在同名文件,会被覆盖
             */
            boolean uploadFlag = false;
            try {
                uploadFlag = ftpClient.storeFile(fileName, inputStream);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ftpClient.logout();
                ftpClient.disconnect();
            }
            if (uploadFlag) {
                System.out.println("上传成功!");
                return true;
            }
            return false;
        }

    打上断点debug,当运行到 

    uploadFlag = ftpClient.storeFile(fileName, inputStream);

    就卡着不到,也不报错。

    百度到很多都说要设置为被动模式,要加:

    ftpClient.enterLocalPassiveMode();

    但是我明明已经加了还是不行。

    于是各种找方法,终于知道问题在哪里了,原来 ftpClient.enterLocalPassiveMode();加的地方不对,要加在建立连接和登录之间才可以。

    现在的代码:

    //FTP文件上传
        public static boolean upload(String hostname, int port, String username, String password,
                                     String targetPath, String fileName, InputStream inputStream) throws SocketException, IOException {
            //实例化ftpClient
            FTPClient ftpClient = new FTPClient();
    
            //设置登陆超时时间,默认是20s
            ftpClient.setDataTimeout(12000);
            //1.连接服务器
            ftpClient.connect(hostname, port);
            ftpClient.enterLocalPassiveMode();
            //2.登录(指定用户名和密码)
            boolean b = ftpClient.login(username, password);
            if (!b) {
                log.info("ftp登陸超時");
                if (ftpClient.isConnected()) {
                    // 断开连接
                    ftpClient.disconnect();
                }
            }
            log.info("ftp登陸成功");
            // 设置字符编码
            ftpClient.setControlEncoding("UTF-8");
            //基本路径,一定存在
            String[] pathArray = targetPath.split("/");
            for (String path : pathArray) {
                if (path.equals("")) {
                    continue;
                }
                //3.指定目录 返回布尔类型 true表示该目录存在
                boolean dirExsists = ftpClient.changeWorkingDirectory(path);
                //4.如果指定的目录不存在,则创建目录
                if (!dirExsists) {
                    //此方式,每次,只能创建一级目录
                    boolean flag = ftpClient.makeDirectory(path);
                    if (!flag) {
                        System.out.println("文件目录创建失败!");
                        return false;
                    }
                    ftpClient.changeWorkingDirectory(path);
                }
            }
            log.info("重新指定上传文件的路径:" + targetPath);
            //重新指定上传文件的路径
    //        ftpClient.changeWorkingDirectory(targetPath);
            //5.设置上传文件的方式
            ftpClient.setBufferSize(1024 * 1024 * 10);
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            /**
             * 6.执行上传
             * remote 上传服务后,文件的名称
             * local 文件输入流
             * 上传文件时,如果已经存在同名文件,会被覆盖
             */
            boolean uploadFlag = false;
            try {
                uploadFlag = ftpClient.storeFile(fileName, inputStream);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ftpClient.logout();
                ftpClient.disconnect();
            }
            if (uploadFlag) {
                System.out.println("上传成功!");
                return true;
            }
            return false;
        }

    问题解决,记录一下爬坑的过程,顺便希望能帮到其他人。

     顺便记录下ftp文件下载

    /**
         * 文件下载--FTP服务器
         */
        @LogRecord(name = "文件下载--FTP服务器")
        @GetMapping(value = "/v1/zdyl/downloadFile")
        public ResultJson downloadFileFtp(HttpServletRequest request, HttpServletResponse response) throws Exception {
            String url = request.getParameter("url");
            if (url == null)
                throw new RRException("url is Empty!");
            URI uri = new URI(url);
            log.info("url:" + url);
            String path = uri.getPath();
            log.info("path:" + path);
            InputStream inputStream = UploadUtil.downloadFile(ftpConfig.getHost(), ftpConfig.getPort(), ftpConfig.getUsername(), ftpConfig.getPassword(), path);
            log.info("fileName:" + path.substring(path.lastIndexOf("/") + 1));
            response.setContentType("application/force-download");
            response.addHeader("Content-disposition", "attachment;fileName=" + path.substring(path.lastIndexOf("/") + 1));
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buf)) != -1) {
                os.write(buf, 0, len);
            }
            return null;
        }
    /**
         * 功能:根据文件名称,下载文件流
         *
         * @return
         * @throws IOException
         */
        public static InputStream downloadFile(String hostname, int port, String username, String password, String remoteFilePath)
                throws IOException {
            InputStream in = null;
            FTPClient ftpClient = null;
            try {
    
                //实例化ftpClient
                ftpClient = new FTPClient();
                //设置登陆超时时间,默认是20s
                ftpClient.setDataTimeout(12000);
                //1.连接服务器
                ftpClient.connect(hostname, port);
                ftpClient.enterLocalPassiveMode();
                //2.登录(指定用户名和密码)
                boolean b = ftpClient.login(username, password);
                if (!b) {
                    log.info("登陸超時");
                    if (ftpClient.isConnected()) {
                        // 断开连接
                        ftpClient.disconnect();
                    }
                }
                log.info("登陸成功");
                // 设置字符编码
                ftpClient.setControlEncoding("UTF-8");
                // 设置传输二进制文件
                ftpClient.setBufferSize(1024 * 1024 * 10);
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    
                int reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    throw new RRException("failed to connect to the FTP Server:");
                }
                // ftp文件获取文件
    
                in = ftpClient.retrieveFileStream(encodingPath(remoteFilePath));
    
            } catch (FTPConnectionClosedException e) {
                log.error("ftp连接被关闭!", e);
                throw e;
            } catch (Exception e) {
                log.error("ERR : upload file " + remoteFilePath + " from ftp : failed!", e);
                throw new RRException("ERR : upload file " + remoteFilePath + " from ftp : failed!");
            } finally {
                ftpClient.disconnect();
            }
            return in;
        }
    
        /**
         * 编码文件路径
         */
        private static String encodingPath(String path) throws UnsupportedEncodingException {
            // FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码
            return new String(path.replaceAll("//", "/").getBytes("GBK"), "iso-8859-1");
        }
  • 相关阅读:
    Sql Server 日期推算处理,格式化处理
    自动升级功能(zt)
    绘制普通的可上下左右布局的RULER(zt)
    合并两个WORD文档,并且修改Word中标签的内容
    Sql Server 中汉字处理排序规则,全角半角
    用函数式编程技术编写优美的 JavaScript(zt)
    什么是序列化?
    日期概念理解中的一些测试
    DataSet,DataTable 不使用EXCEL组件直接保存为EXCEL
    接口测试自动化实践指南
  • 原文地址:https://www.cnblogs.com/wiliamzhao/p/14607507.html
Copyright © 2020-2023  润新知