天天看点

java-ftp 上传、删除文件(支持中文目录、文件名)

java-ftp 上传、删除文件(支持中文目录、文件名)

一、问题

描述:Java中FTPClient上传中文目录、中文文件名乱码问题解决方法

原因:FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。

解决方案:name=new String(name.getBytes("GBK"),"iso-8859-1"); 使用这个转码

二、ftp 上传代码

package me.grass.net;


import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;


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


import me.grass.coder.Debug;
import me.grass.extend.StringExtend;


/**
 *
 * @author xxj
 */
public class FtpHelper implements Closeable {
  private FTPClient ftpClient = null;
  boolean _isLogin = false;
  public static FtpHelper getInstance() {
    return new FtpHelper();
  }
  /**
   * 使用实例
   * @param args
   */
  public static void main(String[] args) {
    FtpHelper ftp = FtpHelper.getInstance();
    
    ftp.login("localhost", 21);
  }


  /**
   * 
   * ftp 匿名登录
   * @param ip ftp服务地址
   * @param port 端口号
   * @param uname 用户名
   * @param pass 密码
   */
  public boolean login(String ip,int port){
    //如果没有设置ftp用户可将username设为anonymous,密码为任意字符串
    return login(ip, port,"anonymous","");
  } 
  /**
   * 
   * ftp登录
   * @param ip ftp服务地址
   * @param port 端口号
   * @param uname 用户名
   * @param pass 密码
   */
  public boolean login(String ip,int port, String uname, String pass) {
    ftpClient = new FTPClient();
//    boolean flag=false;
    try {
      // 连接
      ftpClient.connect(ip,port);
      _isLogin = ftpClient.login(uname, pass);
      Debug.printFormat("ftp:{0}",_isLogin?"登录成功":"登录失败");
      // 检测连接是否成功
      int reply = ftpClient.getReplyCode();
      if (!FTPReply.isPositiveCompletion(reply)) {
        System.err.println("FTP服务器拒绝连接 ");
        return false;
      }
      return true;
    } catch (Exception ex) {
      ex.printStackTrace();
      return false;
    }
  }


  /**
   * 
   * ftp上传文件 
   * @param localFileName 待上传文件
   * @param ftpDirName ftp 目录名
   * @param ftpFileName ftp目标文件
   * @return true||false
   */
  public boolean uploadFile(String localFileName,String ftpDirName, String ftpFileName) {


    Debug.printFormat("准备上传 [{0}] 到 ftp://{1}{2}"
        ,localFileName
        ,ftpDirName
        ,ftpFileName);
    if(StringExtend.isNullOrEmpty(ftpDirName))
      ftpDirName="/";
    if(StringExtend.isNullOrEmpty(ftpFileName))
      throw new RuntimeException("上传文件必须填写文件名!");
    
    //解决中文目录、文件名乱码问题
    try {
      ftpDirName = new String(ftpDirName.getBytes("GBK"),"iso-8859-1");
      ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
    } catch (UnsupportedEncodingException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
      throw new RuntimeException(e1.getMessage(), e1);
    }
    
    File srcFile = new File(localFileName);
    if(!srcFile.exists())
      throw new RuntimeException("文件不存在:"+localFileName);
    
    try (FileInputStream fis = new FileInputStream(srcFile)) {
      // 设置上传目录
      ftpClient.changeWorkingDirectory(ftpDirName);
      ftpClient.setBufferSize(1024);
      //解决上传中文 txt 文件乱码
      ftpClient.setControlEncoding("GBK");
      FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); 
      conf.setServerLanguageCode("zh");  


      // 设置文件类型(二进制)
      ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
      // 上传
      if(ftpClient.storeFile(ftpFileName, fis)){
        fis.close();
        Debug.printFormat("文件上传成功:{0}{1}"
            ,ftpDirName
            ,ftpFileName);
        return true;
      }
      
      return false;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    } finally {
    }
  }


  /**
   * 
   * 删除ftp上的文件
   * 
   * @param ftpFileName
   * @return true || false
   */
  public boolean removeFile(String ftpFileName) {
    boolean flag = false;
    Debug.printFormat("待删除文件:{0}"
        ,ftpFileName);
    try {
      ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
      flag = ftpClient.deleteFile(ftpFileName);
      Debug.printFormat("删除文件:[{0}]"
          ,flag?"成功":"失败");
      return flag;
    } catch (IOException e) {
      e.printStackTrace();
      return false;
    }
  }


  /**
   *
   * 销毁ftp连接
   *
   */
  private void closeFtpConnection() {
    _isLogin = false;
    if (ftpClient != null) {
      if (ftpClient.isConnected()) {
        try {
          ftpClient.logout();
          ftpClient.disconnect();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }


  /**
   *
   * 销毁ftp连接
   *
   */
  @Override
  public void close() {
    this.closeFtpConnection();
  }
}      

三、测试方法

package me.grass.extend;




import static org.junit.Assert.*;


import javax.print.attribute.standard.Finishings;


import org.apache.taglibs.standard.lang.jstl.test.beans.PublicInterface2;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import me.grass.net.FtpHelper;


/** 
*
* @author xxj 
*/
public class FtpHelperTest {
  FtpHelper ftp=null;
  @Before
  public void InitBinder(){
    ftp = FtpHelper.getInstance();
    ftp.login("localhost", 21);//匿名登录
  }
  @After
  public void finish(){
    ftp.close();
  }
  @Test
  public void testUplodaFile() {
    String localFile="D:/Temp/resource/img.jpg";
    String ftpDir="temp";
    String ftpFile=StringExtend.format("img-{0}.jpg"
        , DateExtend.getDate("yyyyMMddHHmmss"));    
    boolean success = ftp.uploadFile(localFile,ftpDir, ftpFile);
    assertTrue(success);
    
    localFile="D:/Temp/resource/text.txt";
    ftpDir="temp";
    ftpFile=StringExtend.format("text-{0}.txt"
        , DateExtend.getDate("yyyyMMddHHmmss"));    
    success = ftp.uploadFile(localFile,ftpDir, ftpFile);    
    assertTrue(success);


    localFile="D:/Temp/resource/文本.txt";
    ftpDir="temp";
    ftpFile=StringExtend.format("文本-{0}.txt"
        , DateExtend.getDate("yyyyMMddHHmmss"));    
    success = ftp.uploadFile(localFile,ftpDir, ftpFile);    
    assertTrue(success);
    
  }
  @Test
  public void testRemove(){
    boolean success = false;
    String file ="/temp/文本-20170509175507.txt";
    success = ftp.removeFile(file);
    
    assertTrue(success);
  }


}