需求
代码直接实现两个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;
}
}