手把手教学 Springboot+ftp+下载图片

简单教学,复制即用的Ftp下载图片
引入配置包

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.9.0</version>
        </dependency>

首先创建连接客户端,中间如果赋值进去找不到变量,则是自己需要配置的 ,比如host:则表示主机ip

public FTPClient connFtp() {
        FTPClient ftpClient = null;
        String errorMsg = null;
        try {
            ftpClient = new FTPClient();
            //设置连接超时时间
            ftpClient.setConnectTimeout(1000 * 30);
            // 连接FTP服务器
            if (port == 0) {
                ftpClient.connect(host);
            } else {
                ftpClient.connect(host, port);
            }
            // 登陆FTP服务器
            ftpClient.login(user, pwd);
            // 中文支持 ,避免图片或文件中文乱码
            ftpClient.setControlEncoding("GBK"); 
            FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
            conf.setServerLanguageCode("zh");
            // 设置文件类型为二进制(如果从FTP下载或上传的文件是压缩文件的时候,不进行该设置可能会导致获取的压缩文件解压失败)
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
                Assert.isTrue(false, ERROR_CONN + "用户名或密码错误");
            } else {
                log.info("FTP连接成功!");
            }
        } catch (Exception e) {
            log.info("登陆FTP失败,请检查FTP相关配置信息是否正确!" + e);
            Assert.isTrue(false, ERROR_CONN + e.getMessage());
            return null;
        }
        return ftpClient;
    }

// deviceId :其实这个是文件名,拼接的,只是我们这以这个id存的文件名,所以用这个
// batch 主要是判断是否需要批量


    @Override
    public List<MultipartFile> getFtpImage(String deviceId, boolean batch) {
        FTPClient ftpClient = connFtp();
        String imgUrl = null;
        List<MultipartFile>  fileList = new ArrayList<>();
        try {
            String path = null;
            String filename = null;
            //指定文件路径 和 路径下的文件名
            path = "/5/panorama/";
             filename = "5_"+deviceId+".jpg";
            //这一步很重要,主要是类似打开目录,
            ftpClient.changeWorkingDirectory(path);
            if(batch){
                FTPFile[] ftpFiles = ftpClient.listFiles();//获取目录下面文件列表,在下面
                for (int i =0;i<ftpFiles.length;i++){
                    FTPFile ftpFile = ftpFiles[i];
                    if (ftpFile.getName().equals(filename)) {
					
                     // 此处表示直接返回到浏览器下载,需要添加参数  HttpServletResponse
                    // response.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(filename, "utf-8"));
                   	// 将文件保存到输出流outputStream中
					//ftpClient.retrieveFile(new String(ftpFile.getName().getBytes("GBK"), "ISO-8859-1"), outputStream);
                   	// ftpclient自带方法 将图片转换成 inputStream 
                		InputStream inputStream = ftpClient.retrieveFileStream(new String(ftpFile.getName().getBytes("GBK"), "ISO-8859-1"));
                        MultipartFile multipartFile = FileUtil.getMultipartFile(inputStream, filename);
                        fileList.add(multipartFile);
                        inputStream.close();
                        System.out.println("ftp获取图片成功。。。。");
                    }
                }
            }else {
                InputStream inputStream = ftpClient.retrieveFileStream(new String(filename.getBytes("GBK"), "ISO-8859-1"));
                MultipartFile multipartFile = FileUtil.getMultipartFile(inputStream, filename);//如果想直接上传的话 到这里就可以调用上传方法了
                fileList.add(multipartFile);
                inputStream.close();
                System.out.println("ftp获取图片成功。。。。");
            }
            ftpClient.logout();
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return fileList;
    }

获取指定目录下的文件列表

 public List<String> getFileNameList(String ftpDirPath) {
        FTPClient ftpClient = connFtp();
        List<String> list = new ArrayList();
        try {
            // 通过提供的文件路径获取FTPFile对象列表
            FTPFile[] files = ftpClient.listFiles(ftpDirPath);
            for (int i = 0; i < files.length; i++) {
                FTPFile ftpFile = files[i];
                if (ftpFile.isFile()) {
                    list.add(ftpFile.getName());
                }
            }
            ftpClient.logout();
        } catch (IOException e) {
            log.error("错误" + e);
        }finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return list;
    }

以下这个方法主要是判断,目录下是否有这个文件,用于某个文件主要判断是否需要录取文件流


    /**
     * 判断ftp服务器文件是否存在
     *
     * @param ftpClient
     * @param path
     * @return
     * @throws IOException
     */
    private static boolean existFile(FTPClient ftpClient, String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }

后续即是扩展内容,将文件流转换成MultipartFile ,剩下的就是正常上传业务逻辑了

 
	import org.apache.commons.fileupload.FileItem;
	import org.apache.commons.fileupload.FileItemFactory;
	import org.apache.commons.fileupload.disk.DiskFileItem;
	import org.apache.commons.fileupload.disk.DiskFileItemFactory;
	
	/**
     * 获取封装得MultipartFile
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return MultipartFile
     */
    public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
        FileItem fileItem = createFileItem(inputStream, fileName);
        //CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
        return new CommonsMultipartFile(fileItem);
    }

    /**
     * FileItem类对象创建
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return FileItem
     */
    public static FileItem createFileItem(InputStream inputStream, String fileName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "file";
        FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        OutputStream os = null;
        //使用输出流输出输入流的字节
        try {
            os = item.getOutputStream();
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            inputStream.close();
        } catch (IOException e) {
            log.error("Stream copy exception", e);
            throw new IllegalArgumentException("文件上传失败");
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);

                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);
                }
            }
        }
        return item;
    }

总结起来,开发中主要遇到的问题:
1,文件命名不规范,导致拉取失败
2,文件中文乱码,导致找不到
有不懂的或理解不到的,可以留言,相互探讨

补充:特殊图片格式使用此方式有问题
可以采用下载后读取上传

    public static void downLocal() throws IOException {
        FTPClient ftpClient = connectFtpServer();
        // 设置文件类型
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftpClient.changeWorkingDirectory(path);
        // 设置要下载的文件名称
        String fileName = "5_1663186150934798337.tif";
        // 创建输出流,传入要下载的位置
        FileOutputStream out = new FileOutputStream("E:\\www\\ffw\\images\\quanjing\\20230913\\" + "798337.jpg");
        ftpClient.retrieveFile(fileName, out);
        out.close();
        System.out.println("下载成功");
    }

你可能感兴趣的:(组件开发配置,spring,boot,后端,java)