最近因为使用FTP实现上传下载,因为已经有前辈使用了,照着敲了一遍(绝对没有复制粘贴啊,发誓)。但是今天突然发现FTPClient还不一样,仔细看了看,一个是sun.net.ftp.FtpClient,一个是org.apache.commons.net.ftp.FTPClient,吓得我赶紧在网上找了找区别,仔细一看区别不是太大,还是不够细心啊,一开始竟然没发现不一样,还好亡羊补牢为时未晚。

首先我们来看一下sun的FtpClient代码:

public static boolean uploadFileBySun(StringBuffer fileContent,String server,String userName, String userPassword, String path, 
    String fileName) {
FtpClient ftpClient = new FtpClient();
try {
//打开ftp服务器
ftpClient.openServer(server);
//使用指定用户登录
ftpClient.login(userName, userPassword);
//转到指定路径
ftpClient.cd(path);
TelnetOutputStream os = null;
//新建一个文件
// os = ftpClient.put(new String(fileName.getBytes("GBK"), "iso-8859-1"));
os = ftpClient.put(fileName);
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(fileContent.toString());
bw.flush();
bw.close();
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
} finally {
try {
//关闭ftp连接
ftpClient.closeServer();
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}

  正如上面的代码,上传文件分为六步,第一步,打开ftp服务器,第二步,使用指定用户名以及密码登陆,第三步,转到指定文件路径,第四步,创建一个文件,第五步,往文件里面写东西,并关闭文件,第六步,释放ftp连接。最后一步释放ftp连接很重要,一般ftp服务器连接数都是有限的,所以不管文件上传成功或是失败都必须释放连接。

  上面这个例子上传的文件是字符串文本,必须要提的是,如果上传的字符串文本较长(我项目中上传的文本大概在160kb上下),使用上面的方法可能会出现字符串丢失的情况,原因不明,可能跟缓存有关,所以如果文本较长,建议用户使用字节流。还有一个问题,如果要上传的文件名是中文的话,上传的文件名将是乱码,乱码问题我尝试许多转码也解决不了,于是不得不使用下面的方法了。

接下来就是Apache的FTPClient代码:

public static boolean uploadFileByApacheByBinary(StringBuffer fileContent,String server,String userName, String userPassword, 
    String path, String fileName) {
FTPClient ftpClient = new FTPClient();
try {
InputStream is = null;
is = new ByteArrayInputStream(fileContent.toString().getBytes());
ftpClient.connect(server);
ftpClient.login(userName, userPassword);
ftpClient.changeWorkingDirectory(path);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.storeFile(new String(fileName.getBytes("GBK"), "iso-8859-1") , is);
is.close();
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if(ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return true;
}

  Apache上传文件的步骤跟sun的实现基本一致,只是方法名有些区别而已。在这里我将字符串文本转换成了ByteArrayInputStream字节缓冲流,这是个很有用的东西,常用来进行字符到流的转换。转换成字节上传就不会出现丢失文件内容的情况了。

  ftpClient.storeFile(new String(fileName.getBytes(“GBK”), “iso-8859-1″) , is)这句代码将is输入流的东西上传到ftp服务器的fileName文件中,在这里我们对fileName文件名进行了转码,经测试中文没有乱码(ftp服务器使用的是window,其他平台未测试),而如果我们使用sun的ftp实现,即使文件名进行这样类似的转码,依然是乱码。 
  两种方法大家可以根据自己需要选择, 如果使用Apache的FTPClient的,我们需要在工程里面加入commons-net.jar。

原文转自:http://ower22.iteye.com/blog/2126633

sun公司和apache使用ftpclient的区别的更多相关文章

  1. [转载]一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    本文转载自:http://blog.csdn.net/testcs_dn/article/details/38496107 开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区 ...

  2. 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    一张图看懂开源许可协议,开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源许可证GPL.BSD.MIT.Mozi ...

  3. 转)GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 以下是上述协议的简单介绍: BSD开源协议 BSD开源协议是一个给于使用者很大自由的协议.基本上使用者可以”为所欲为”, ...

  4. 开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别(转)

    因CooCox用户数及影响力越来越大,CooCox团队也逐渐提高了对软件及代码协议的重视.在收集整理的过程中,一些归纳好的信息和大家分享一下.首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源 ...

  5. 【转】 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    原文:http://blog.csdn.net/testcs_dn/article/details/38496107 ----------------------------------------- ...

  6. [转帖]开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 https://www.geek-workshop.com/thread-1860-1-1.html     liamj ...

  7. 转载:开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    转自:https://www.cnblogs.com/findumars/p/6309048.html 首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源许可证GPL.BSD.MIT.Mozi ...

  8. 如何从sun公司官网下载java API文档(转载)

    相信很多同人和我一样,想去官网下载一份纯英文的java API文档,可使sun公司的网站让我实在很头疼,很乱,全是英文!所以就在网上下载了别人提供的下载!可是还是不甘心!其实多去看看这些英文的技术网站 ...

  9. Apache/Tomcat/JBOSS/Nginx区别

    先说Apache和Tomcat的区别: Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. ...

随机推荐

  1. scanf()函数释疑(word找的,没源地址了)

    scanf()函数释疑(上) 一.序言 scanf()函数的控制串的使用 例1. #include "stdio.h" int main(void) { int a,b,c; sc ...

  2. C#委托的进一步学习

    一.委托的说明 namespace LearningCsharp { class Program { //定义一个委托,使用delegate加上方法签名 //将委托理解为存储方法的"数组&q ...

  3. linux(5)查看历史命令执行记录history

    前言 我们每次敲打linux命令的时候,有时候想用之前用过的命令,一般情况下,我们都会按↑↓箭头来寻找历史的命令记录,那如果我想用1天前执行的某条命令,难道还要按↑100次?显示这样是不现实的,我们可 ...

  4. ApiTesting全链路自动化测试框架 - 初版发布(一)

    简介 此框架是基于Python+Pytest+Requests+Allure+Yaml+Json实现全链路接口自动化测试. 主要流程:解析接口数据包 ->生成接口基础配置(yml) ->生 ...

  5. cmath取整函数

    #include <iostream> #include <cmath>//头文件 using namespace std; int main () { double n; c ...

  6. Codeforces 1144F Graph Without Long Directed Paths DFS染色

    题意: 输入一张有向图,无自回路和重边,判断能否将它变为有向图,使得图中任意一条路径长度都小于2. 如果可以,按照输入的边的顺序输出构造的每条边的方向,构造的边与输入的方向一致就输出1,否则输出0. ...

  7. Linux系统编程【2】——编写who命令

    学到的知识点 通过实现who命令,学到了: 1.使用man命令寻找相关信息 2.基于文件编程 3.体会到c库函数与系统调用的不同 4.加深对缓冲技术的理解 who命令的作用 who命令的使用 在控制终 ...

  8. 僵尸进程 & 孤儿进程

    参考博文 基本概念 僵尸进程:是所有进程都会进入的一种进程状态,子进程退出,而父进程并没有调用 wait() 或 waitpid() 获取子进程的状态信息,那么子进程的 PID 和 进程描述符 等资源 ...

  9. Excel导出时设置单元格的格式为文本

    问题: 用excel导出数据时,如何设置单元格格式的数字分类为"文本",默认是"常规"? 比如:导出编码0235A089,在Excel查看默认显示的是没有前面的 ...

  10. 记一次 lampiao渗透(Drupal+脏牛提权)

    vulnhub|渗透测试lampiao 题记 最近在打靶机,发现了一个挺有意思的靶机,这里想跟大家分享一下. 环境准备 vulnhub最近出的一台靶机 靶机(https://www.vulnhub.c ...