【ftp2ftp】文件以字节流的形式冲FTP1传输到FTP2,中间出现文件传输失败的问题(只传输了一半,文件损坏)

需求

代码直接实现两个ftp之间的文件相互传输

实现逻辑

①ftp1的file转变成inputStream
②inputStream转变为字符集byte[]
③字符集写入ftp2的outputStream中

问题代码简述

逻辑①的内容inputStream转化为字符集byte[]后我直接:

byte[] buffer = IOUtils.toByteArray(inputStream);
outputStream.write(buffer);

可以看到我转化完成之后直接就写入了,但是没考虑到,outputStream.write(buffer),这个方法是是异步的,写入这个操作和代码是并行的,而且有一个问题就是,我下面有一个ftpclient的关闭,我把ftp给关了,那文件写一半,没了!嗝屁了
在这里插入图片描述
错误传输的结果展示:
在这里插入图片描述

正确的代码

/**
     * 分段写入 byte
     * @param buffer 字符集
     * @param outputStream 输出流
     * @param divisor 除数,就是把字符集分成等份的长度
     * @throws IOException
     */
    public static  void writeByte(byte[] buffer,OutputStream outputStream,int divisor) throws IOException {
        int num = divisor;
        int cs = buffer.length/divisor;
        int finalNum = buffer.length - cs*num;
        int startNum = 0;
        for(int i = 0; i < cs; i++) {
            outputStream.write(buffer,startNum,num);
            startNum = startNum + num;
        }
        outputStream.write(buffer,cs*num,finalNum);
        outputStream.flush();
        outputStream.close();
    }

代码合集

package com.example.demo;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ftp2FtpByByte {

    public static void main(String arg[]) throws Exception {
        //String sourcefilePath = "D:\\ftp\\sourceCsv\\演示文稿1(1).pptx";
        String sourceFilePath = "/sourceCsv/";
        String filename = "1111.jpeg";
        String host = "127.0.0.1";
        int port = 21;
        String username = "wx";
        String password = "123456";
        String targetFilePath = "/target/";
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddhhmmss");
        ftp2Ftp( host, port, username, password, sourceFilePath+"\\"+filename, targetFilePath+"\\"+sf.format(new Date())+filename);
    }

    public static void ftp2Ftp(String host, int port, String username, String password, String sourceFilePath, String targetFilePath) throws Exception {
        FTPClient ftpClient = getConnect(host, port, username, password);
        InputStream inputStream =  getInputStream(ftpClient, sourceFilePath);
        /*获取的inputSteam 转化为byte 然后写入*/
        byte[] buffer = IOUtils.toByteArray(inputStream);
        inputStream.close();
        FTPClient ftpClientNew = getConnect(host, port, username, password);
        OutputStream outputStream = getOutputStream( ftpClientNew, targetFilePath);
        writeByte(buffer,outputStream);
        ftpClient.disconnect();
        ftpClientNew.disconnect();
    }

    /**
     * 分段写入 byte
     * @param buffer
     * @param outputStream
     * @throws IOException
     */
    public static  void writeByte(byte[] buffer,OutputStream outputStream) throws IOException {
        int num = 1024;
        int cs = buffer.length/1024;
        int finalNum = buffer.length - cs*num;
        int startNum = 0;
        for(int i = 0; i < cs; i++) {
            outputStream.write(buffer,startNum,num);
            startNum = startNum + num;
        }
        outputStream.write(buffer,cs*num,finalNum);
        outputStream.flush();
        outputStream.close();
    }




    public static InputStream getInputStream(FTPClient ftpClient,String filePath) {
        try {
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            String filepath2 = new String(filePath.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING);
            return ftpClient.retrieveFileStream(filepath2);
        } catch (IOException e) {
            String message = String.format("读取文件 : [%s] 时出错,请确认文件:[%s]存在且配置的用户有权限读取", filePath, filePath);
            return  null;
        }
    }


    public static OutputStream getOutputStream(FTPClient ftpClient, String filePath) {
        try {
            String parentDir = filePath.substring(0,StringUtils.lastIndexOf(filePath, IOUtils.DIR_SEPARATOR));
            ftpClient.changeWorkingDirectory(new String(parentDir.getBytes("GBK"),FTP.DEFAULT_CONTROL_ENCODING));
            ftpClient.setBufferSize(1024);
            String ftpPath2 = new String(filePath.getBytes("GBK"),FTP.DEFAULT_CONTROL_ENCODING);

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            OutputStream writeOutputStream = ftpClient.appendFileStream(ftpPath2);
            String message = String.format(
                    "打开FTP文件[%s]获取写出流时出错,请确认文件%s有权限创建,有权限写出等", filePath,
                    filePath);
            if (null == writeOutputStream) {
                System.out.println(message);
            }

            return writeOutputStream;
        } catch (IOException e) {
            String message = String.format(
                    "写出文件 : [%s] 时出错,请确认文件:[%s]存在且配置的用户有权限写, errorMessage:%s",
                    filePath, filePath, e.getMessage());
            System.out.println(message);
            return null;
        }
    }


    public static FTPClient getConnect(String host, int port, String username, String password) throws IOException {
        FTPClient ftp = new FTPClient();
        ftp.connect(host, port);// 连接FTP服务器
        int reply;
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
        ftp.login(username, password);// 登录
        reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
        }
        return ftp;
    }



}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值