写道
Apache Commom net:
1) 递归path,调用changeWorkingDirectory改变工作目录并验证是否存在
然后直接调用retrieveFileStream(filename),filename不用带路径,path经过编码后,filename带全路径存在问题;
2)编码方式统一用new String(filename.getBytes("UTF-8"),"iso-8859-1")
3)ftpClient.getSystemType()获取FTP服务器操作系统,动态设置编码
写道
问题:1)原下载图片时直接返回InputStream,然后在业务代码位置获取数据时阻塞无响应,错误信息:toString() unavailable - no suspended threads
对于网络流InputStream available经常返回0,即网络存在延时,方法执行完后立刻关闭连接,数据还未接收完或正在接收中时被关闭,倒致InputStream read方法阻塞。
public static InputStream getBytes(URL url){
FTPClient ftpClient = null;
InputStream inputStream = null;
String filename = null;
String pathname = null;
String fullpath = null;
String host = url.getHost();
String user = "anonymous";
String pass ="";
int port = url.getPort();
String path = url.getPath();
String userInfo = url.getUserInfo();
try {
if (userInfo != null) { // get the user and password
int delimiter = userInfo.indexOf(':');
if (delimiter != -1) {
user = userInfo.substring(0, delimiter++);
pass = userInfo.substring(delimiter);
}
}
ftpClient = getClient(host, user, pass, port);
if(!path.endsWith("/")){
int i = path.lastIndexOf('/');
if(i>0){
filename=path.substring(i+1,path.length());
pathname=path.substring(0,i);
}else{
filename=path;
pathname=null;
}
} else {
pathname=path.substring(0,path.length()-1);
filename=null;
}
if(pathname!=null){
fullpath=pathname+"/"+(filename!=null?filename:"");
}else{
fullpath = filename;
}
// 编码后的pathname
StringBuffer sb = new StringBuffer();
ftpClient.setControlEncoding("UTF-8");
String encodeFileName = new String(filename.getBytes("UTF-8"),FTP_ENCODE);
StringTokenizer token = new StringTokenizer(path,"/");
long a = System.currentTimeMillis();
while (token.hasMoreTokens()){
String fold = token.nextToken();
// 中文编码
String encodeFold = new String(fold.getBytes("UTF-8"),FTP_ENCODE);
boolean flag = ftpClient.changeWorkingDirectory(encodeFold);
if(!flag){
System.out.println("目录不存在:"+fold);
System.out.println("指定的目录不存在或ftp无法打开,路径为:"+pathname);
break;
}
sb.append(encodeFold);
if(token.hasMoreTokens()){
sb.append("/");
} else {
sb.append("/");
sb.append(encodeFileName);
}
}
long b = System.currentTimeMillis();
inputStream=ftpClient.retrieveFileStream(encodeFileName);
} catch (FTPConnectionClosedException e) {
System.err.println("Server closed connection.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException f) {
// do nothing
}
}
}
return inputStream;
}
写道
数据获取完后,再关闭连接。升级后正常
package com.sunshine.app.util.ftp;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.StringTokenizer;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
public abstract class FtpTools {
private static String FTP_ENCODE = "iso-8859-1";
private static byte[] EMPTY_BYTE = new byte[0];
public static FTPClient getClient(String host, String user, String pass, int port){
FTPClient ftpClient = null;
ftpClient = new FTPClient();
try {
ftpClient.connect(host, port);
int defaultTimeout = 30 * 60 * 1000;
ftpClient.setConnectTimeout(3 * 1000);
ftpClient.setControlKeepAliveTimeout(defaultTimeout);
ftpClient.setControlKeepAliveReplyTimeout(defaultTimeout);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
System.err.println("FTP server refused connection.");
}
} catch (IOException e) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
}
try
{
if (!ftpClient.login(user, pass)){
ftpClient.logout();
}
System.out.println("Remote system is " + ftpClient.getSystemType());
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// Use passive mode as default because most of us are
// behind firewalls these days.
//ftpClient.enterLocalActiveMode();
ftpClient.enterLocalPassiveMode();
ftpClient.setUseEPSVwithIPv4(false);
}catch(FTPConnectionClosedException e){
System.err.println("Server closed connection.");
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException f) {
// do nothing
}
}
}
return ftpClient;
}
public static byte[] getBytes(URL url){
FTPClient ftpClient = null;
InputStream inputStream = null;
String filename = null;
String pathname = null;
String fullpath = null;
String host = url.getHost();
String user = "anonymous";
String pass ="";
int port = url.getPort();
String path = url.getPath();
String userInfo = url.getUserInfo();
try {
if (userInfo != null) { // get the user and password
int delimiter = userInfo.indexOf(':');
if (delimiter != -1) {
user = userInfo.substring(0, delimiter++);
pass = userInfo.substring(delimiter);
}
}
ftpClient = getClient(host, user, pass, port);
if(!path.endsWith("/")){
int i = path.lastIndexOf('/');
if(i>0){
filename=path.substring(i+1,path.length());
pathname=path.substring(0,i);
}else{
filename=path;
pathname=null;
}
} else {
pathname=path.substring(0,path.length()-1);
filename=null;
}
if(pathname!=null){
fullpath=pathname+"/"+(filename!=null?filename:"");
}else{
fullpath = filename;
}
// 编码后的pathname
StringBuffer sb = new StringBuffer();
ftpClient.setControlEncoding("UTF-8");
String encodeFileName = new String(filename.getBytes("UTF-8"),FTP_ENCODE);
StringTokenizer token = new StringTokenizer(path,"/");
long a = System.currentTimeMillis();
while (token.hasMoreTokens()){
String fold = token.nextToken();
// 中文编码
String encodeFold = new String(fold.getBytes("UTF-8"),FTP_ENCODE);
boolean flag = ftpClient.changeWorkingDirectory(encodeFold);
if(!flag){
System.out.println("目录不存在:"+fold);
System.out.println("指定的目录不存在或ftp无法打开,路径为:"+pathname);
break;
}
sb.append(encodeFold);
if(token.hasMoreTokens()){
sb.append("/");
} else {
sb.append("/");
sb.append(encodeFileName);
}
}
long b = System.currentTimeMillis();
inputStream=ftpClient.retrieveFileStream(encodeFileName);
long c = System.currentTimeMillis();
System.out.println("CD--"+(b-a) + " RF--" + (c-b));
if(inputStream == null)
return EMPTY_BYTE;
return transferToByteArray(inputStream);
} catch (FTPConnectionClosedException e) {
System.err.println("Server closed connection.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException f) {
// do nothing
}
}
}
return EMPTY_BYTE;
}
public static byte[] transferToByteArray(InputStream input){
BufferedInputStream bi = null;
ByteArrayOutputStream barray = null;
try {
byte[] buffer = new byte[1024];
bi = new BufferedInputStream(input);
barray = new ByteArrayOutputStream();
int len = 0;
while((len=bi.read(buffer))!=-1){
barray.write(buffer, 0, len);
}
barray.flush();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(barray != null)
barray.close();
if(bi != null)
bi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return barray.toByteArray();
}
}