retrievefile文件字节为0_FTP上传文件0字节问题

2023-05-16

这几天在做一个FTP上传文件的功能,在本地运行完全没有问题,上传文件成功。在公网(centos系统)上进行测试的时候就出了问题了,上传一直卡到storeFile上,一般是会卡住30-60秒,然后返回“false”,不报异常。所以我又开始怀疑代码的问题,在本地建了个CentOS的虚拟机,安装vsftp,结果是成功的。使用FTP上传工具进行处理,公网上传下载一点问题都没有,不会出现0字节的问题,至此,我就十分无耐了,同样的代码,在不同环境上支行的效果居然不一样。

没办法,我只能想常规的想法一样,开始怀疑环境问题,按照说明,对公网的vsftp重新整了一遍,结果还是一样的,我去,什么鬼。

在百度搜到了千千万万的处理方法,一个的试,都没有处理好。其中有一个文章说到FTP的模式,VSFTP有两种模式:pasv模式与port模式,什么意思,不懂,再搜索一下。

Port模式:

当客户端C向服务端S连接后,使用的是Port模式,那么客户端C会发送一条命令告诉服务端S(客户端C在本地打开了一个端口N在等着你进行数据连接),当服务端S收到这个Port命令后 就会向客户端打开的那个端口N进行连接,这种数据连接就生成了。

Pasv模式:

当客户端C向服务端S连接后,服务端S会发信息给客户端C,这个信息是(服务端S在本地打开了一个端口M,你现在去连接我吧),当客户端C收到这个信息后,就可以向服务端S的M端口进行连接,连接成功后,数据连接也建立了。

从上面的解释中,大家可以看到两种模式主要的不同是数据连接建立的不同,对于Port模式,是客户端C在本地打开一个端口等服务端S去连接建立数据连接;而Pasv模式就是服务端S打开一个端口等待客户端C去建立一个数据连接。

默认情况下,FTPCLIENT用的是port模式,可以在FTPCLIENT原码中看到

private void__initDefaults(){

this.__dataConnectionMode = 0;

....

}

public voidenterLocalActiveMode() {

this.__dataConnectionMode = 0;

this.__passiveHost = null;

this.__passivePort = -1;

}

public voidenterLocalPassiveMode() {

this.__dataConnectionMode = 2;

this.__passiveHost = null;

this.__passivePort = -1;

} 不知道是不是这个问题,试一下吧,反正模式是客户端发起的,代码上加入ftpClient.enterLocalPassiveMode();

直接运行,成功。

附上ftp上传与下载代码:

import org.apache.commons.io.IOUtils;

import org.apache.commons.net.ftp.FTPClient;

import java.io.*;

import java.util.logging.Logger;

/**

* 含义:ftp的上传下载处理对象

*/

public class FtpFileTransfer {

private FTPClient ftpClient = null;//ftp客户端对象

private static String hostname = null;//FTP主机名称

private static Integer port = 0;//FTP服务端口

private static String userName = null;//FTP服务器登录用户名

private static String passwd=null;//FTP服务器登录密码

private final String SPAPRATE_TOEKN = "/";

private Logger logger = Logger.getLogger(this.getClass().getName());

/**

* 从配置文件中获取配置值

*/

public FtpFileTransfer(String hostname,int port,String userName,String passwd){

this.hostname = hostname;

this.port = port;

this.userName = userName;

this.passwd = passwd;

}

/**

* 方法描述:上传文件

* @param srcPath 源文件路径

* @param ftpPath FTP端存放路径

* @param targetName FTP端存放名称

* @return 操作是否成功

*/

public boolean uploadFile(String srcPath,String ftpPath, String targetName){

boolean ret = false;

File file = new File(srcPath);

ret = uploadFile(file, ftpPath, targetName);

return ret;

}

/**

* 方法描述:上传文件

* @param file 待上传的文件

* @param ftpPath 目标文件路径

* @param targetName 目标名称

* @return

*/

public boolean uploadFile(File file,String ftpPath,String targetName){

if(file == null){

logger.info("File is null");

return false;

}

try {

InputStream is = new FileInputStream(file);

return uploadFileStream(is, ftpPath, targetName);

} catch (FileNotFoundException e) {

return false;

}

}

/**

* 方法描述:上传文件

* @param is 源文件流

* @param ftpPath 放置在服务器上的位置

* @param targetName 放置在服务器上的名称

* @return 操作是否成功

*/

public boolean uploadFileStream(InputStream is,String ftpPath, String targetName){

boolean ret = false;

if(is == null){

logger.info("File is null");

return ret;

}

ret = this.connect2Ftp();

if(!ret){

logger.info("connect to ftp server failure");

this.disconnect2Ftp();

return ret;

}

try {

boolean mkdir = this.makeDir(ftpPath);

if(ftpPath.startsWith(SPAPRATE_TOEKN)){

ftpPath = ftpPath.substring(ftpPath.indexOf(SPAPRATE_TOEKN)+SPAPRATE_TOEKN.length());

}

ret = ftpClient.changeWorkingDirectory(ftpPath);

if(ret){

ftpClient.setBufferSize(1024);

ftpClient.setControlEncoding("utf-8");

ftpClient.enterLocalPassiveMode();

ret = ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

if(ret){

ret = ftpClient.storeFile(targetName, is);

}

}

} catch (IOException e) {

e.printStackTrace();

throw new RuntimeException("FTP客户端出错!", e);

} finally {

IOUtils.closeQuietly(is);

disconnect2Ftp();

}

return ret;

}

/**

* 方法描述:下载文件

* @param remoteFileName FTP上的文件名称,含路径

* @param localFilePath 取到文件到本地后文件的存放位置

* @return 操作是否成功

*/

public boolean downloadFile(String remoteFileName, String localFilePath){

boolean ret = false;

remoteFileName = remoteFileName.trim();

if(remoteFileName.startsWith(SPAPRATE_TOEKN)){

remoteFileName = remoteFileName.substring(remoteFileName.indexOf(SPAPRATE_TOEKN)

+SPAPRATE_TOEKN.length());

}else if(remoteFileName.startsWith("\\")){

remoteFileName = remoteFileName.substring(remoteFileName.indexOf("\\")

+"\\".length());

}

String path = null;

if(!remoteFileName.contains("//")){

if(remoteFileName.contains("/")){

remoteFileName=remoteFileName.replace("/", "\\");

}

}

path = remoteFileName.substring(0,remoteFileName.lastIndexOf("\\"));

String fileName = remoteFileName.substring(path.length()+2);

FileOutputStream fos = null;

try {

ret = connect2Ftp();

if(!ret){

disconnect2Ftp();

return ret;

}

ret = ftpClient.changeWorkingDirectory(path);

fos = new FileOutputStream(localFilePath);

ftpClient.setBufferSize(1024);

ftpClient.setControlEncoding("utf-8");

//设置文件类型(二进制)

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

ret = ftpClient.retrieveFile(fileName, fos);

} catch (IOException e) {

throw new RuntimeException("FTP客户端出错!", e);

} finally {

IOUtils.closeQuietly(fos);

disconnect2Ftp();

}

return ret;

}

/**

* 方法描述:删除FTP服务器上的文件

* @param filePath 文件名称

* @return 删除成功/失败

*/

public boolean deleteFile(String filePath){

boolean ret = false;

if(filePath == null || filePath.isEmpty() || filePath.equals("")){

return false;

}

try {

connect2Ftp();

ftpClient.changeWorkingDirectory("\\");

ret = ftpClient.deleteFile(filePath);

} catch (IOException e) {

}finally{

disconnect2Ftp();

}

return ret;

}

/**

* 方法描述:删除文件夹

* @param dirPath 文件夹路径

* @param force 是否强制删除

* @return 是否删除成功

*/

public boolean deleteDirs(String dirPath, boolean force){

boolean ret = false;

if(dirPath.startsWith(SPAPRATE_TOEKN)){

dirPath = dirPath.substring(dirPath.indexOf(SPAPRATE_TOEKN)+SPAPRATE_TOEKN.length());

}

String path = dirPath;

try {

ret = ftpClient.changeWorkingDirectory(dirPath);

String[] names = ftpClient.listNames();

if(force){

for(String name:names){

if(dirPath.endsWith(SPAPRATE_TOEKN)){

ret = deleteFile(dirPath+name);

}else{

ret = deleteFile(dirPath+SPAPRATE_TOEKN+name);

}

}

}

ret = ftpClient.changeWorkingDirectory("//");

while(true){

ret = ftpClient.removeDirectory(path);

if(path.contains(SPAPRATE_TOEKN)){

path = path.substring(0, path.lastIndexOf(SPAPRATE_TOEKN));

}else{

break;

}

}

} catch (Exception e) {

}

return ret;

}

/**

* 方法描述:连接到远端的FTP服务器

* @return 是否连接成功

*/

private boolean connect2Ftp(){

boolean ret = false;

ftpClient = new FTPClient();

try {

ftpClient.connect(hostname, port);

ret = ftpClient.login(userName, passwd);

logger.info("Finished login the ftp server, result="+ret);

} catch (Exception e) {

}

return ret;

}

/**

* 方法描述:断开ftp链接

*/

private void disconnect2Ftp(){

if(ftpClient != null){

try {

ftpClient.disconnect();

} catch (IOException e) {

}

}

}

/**

* 方法描述:根据目录要求创建ftp端的文件夹路径

* @param dir 文件夹路径,如:绝对路径,/ab/cde/ef/hg,相对路径, ab/cd

* @return 是否创建成功

* @throws IOException

*/

private boolean makeDir(String dir) throws IOException{

boolean ret = false;

int i = 0;

if(dir != null && !dir.isEmpty()){

String[] dirs = null;

int len = 0;

if(dir.contains("//")){

dir = dir.replace("//", SPAPRATE_TOEKN);

i = 1;

}

if(dir.contains(SPAPRATE_TOEKN)){

dirs = dir.split(SPAPRATE_TOEKN);

len = dirs.length;

StringBuffer sb = new StringBuffer();

for(;i

sb.append(dirs[i]);

sb.append(SPAPRATE_TOEKN);

ret = ftpClient.makeDirectory(sb.toString());

}

}else{

ret = ftpClient.makeDirectory(dir);

}

}

return ret;

}

public boolean isFileExist(String filePath) {

connect2Ftp();

boolean ret = false;

try {

String rt = ftpClient.getModificationTime(filePath);

if (rt != null && !rt.isEmpty()) {

ret = true;

}

} catch (IOException e) {

} finally {

disconnect2Ftp();

}

return ret;

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

retrievefile文件字节为0_FTP上传文件0字节问题 的相关文章

随机推荐