package servlet;import java.io.*; import java.net.*; import java.util.*;@SuppressWarnings("deprecation") public class FTP { // FOR INITIAL DEBUGGING: set the variable to "true" private boolean DEBUG = true; //private static final int CNTRL_PORT = 21; private Socket csock = null; private Socket dsock = null; private DataInputStream dcis; private PrintStream pos; // constructor needs servername, username and passwd public FTP(String server,int port, String user, String pass) { try { ftpConnect(server,port); ftpLogin(user, pass); } catch(IOException ioe) {ioe.printStackTrace();} } public void download(String dir, String file, boolean asc, String dest) throws Exception { int BUFSIZE = 1000; byte[] buf = new byte[BUFSIZE]; int i;
if (DEBUG) { System.out.println("Downloading " + file); } ftpSetDir(dir); ftpSetTransferType(asc); dsock = ftpGetDataSock(); BufferedInputStream in = new BufferedInputStream(dsock.getInputStream(), BUFSIZE); FileOutputStream out = new FileOutputStream(dest); ftpSendCmd("RETR "+file); while ((i = in.read(buf)) != -1) { out.write(buf, 0, i); out.flush(); } in.close(); out.close(); ftpLogout(); } private void ftpConnect(String server,int port) throws IOException { // Set up socket, control streams, connect to ftp server // Open socket to server control port 21 csock = new Socket(server, port); // Open control streams InputStream cis = csock.getInputStream(); dcis = new DataInputStream(cis); OutputStream cos = csock.getOutputStream(); pos = new PrintStream(cos); // handle more than one line returned String reply = dcis.readLine(); String numerals = reply.substring(0, 3); String hyph_test = reply.substring(3, 4); String next = null; if(hyph_test.equals("-")) { boolean done = false; while(!done) { // read lines til find "" -> last line next = dcis.readLine(); if(next.substring(0,3).equals(numerals) && next.substring(3, 4).equals(" ")) done = true; } } if(numerals.substring(0,3).equals("220")) // ftp server alive ; // System.out.println("Connected to ftp server"); else System.err.println("Error connecting to ftp server."); } private Socket ftpGetDataSock() throws IOException { // Go to PASV mode, capture server reply, parse for socket setup // V2.1: generalized port parsing, allows more server variations String reply = ftpSendCmd("PASV"); // New technique: just find numbers before and after ","! StringTokenizer st = new StringTokenizer(reply, ","); String[] parts = new String[6]; // parts, incl. some garbage int i = 0; // put tokens into String array while(st.hasMoreElements()) { // stick pieces of host, port in String array try { parts[i] = st.nextToken(); i++; } catch(NoSuchElementException nope){nope.printStackTrace();} } // end getting parts of host, port // Get rid of everything before first "," except digits String[] diggies = new String[3]; for(int j = 0; j < 3; j++) { // Get 3 characters, inverse order, check if digit/character diggies[j] = parts[0].substring(parts[0].length() - (j + 1), parts[0].length() - j); // next: digit or character? if(!Character.isDigit(diggies[j].charAt(0))) diggies[j] = ""; } parts[0] = diggies[2] + diggies[1] + diggies[0]; // Get only the digits after the last "," String[] porties = new String[3]; for(int k = 0; k < 3; k++) { // Get 3 characters, in order, check if digit/character // May be less than 3 characters if((k + 1) <= parts[5].length()) porties[k] = parts[5].substring(k, k + 1); else porties[k] = "FOOBAR"; // definitely not a digit! // next: digit or character? if(!Character.isDigit(porties[k].charAt(0))) porties[k] = ""; } // Have to do this one in order, not inverse order parts[5] = porties[0] + porties[1] + porties[2]; // Get dotted quad IP number first String ip = parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3]; // Determine port int port = -1; try { // Get first part of port, shift by 8 bits. int big = Integer.parseInt(parts[4]) << 8; int small = Integer.parseInt(parts[5]); port = big + small; // port number } catch(NumberFormatException nfe) {nfe.printStackTrace();} if((ip != null) && (port != -1)) dsock = new Socket(ip, port); else throw new IOException(); return dsock; } private void ftpLogin(String user, String pass) throws IOException { ftpSendCmd("USER "+user); ftpSendCmd("PASS "+pass); } private void ftpLogout() {// logout, close streams try { if(DEBUG) System.out.println("sending BYE"); pos.print("BYE" + "\r\n" ); pos.flush(); pos.close(); dcis.close(); csock.close(); dsock.close(); } catch(IOException ioe) {ioe.printStackTrace();} } private String ftpSendCmd(String cmd) throws IOException { // This sends a dialog string to the server, returns reply // V2.0 Updated to parse multi-string responses a la RFC 959 // Prints out only last response string of the lot. pos.print(cmd + "\r\n" ); String reply = dcis.readLine(); String numerals = reply.substring(0, 3); String hyph_test = reply.substring(3, 4); String next = null; if(hyph_test.equals("-")) { boolean done = false; while(!done) { // read lines til find "" -> last line next = dcis.readLine(); if(next.substring(0,3).equals(numerals) && next.substring(3, 4).equals(" ")) done = true; } if(DEBUG) System.out.println("Response to: "+cmd+" was: "+next); return next; } else if(DEBUG) System.out.println("Response to: "+cmd+" was: "+reply); return reply; } private void ftpSetDir(String dir) throws IOException { // cwd to dir ftpSendCmd("CWD "+dir); } private void ftpSetTransferType(boolean asc) throws IOException { // set file transfer type String ftype = (asc? "A" : "I"); ftpSendCmd("TYPE "+ftype); } ///////////////// private fields //////////////////// private String getAsString(InputStream is) { int c=0; char lineBuffer[]=new char[128], buf[]=lineBuffer; int room= buf.length, offset=0; try { loop: while (true) { // read chars into a buffer which grows as needed switch (c = is.read() ) { case -1: break loop; default: if (--room < 0) { buf = new char[offset + 128]; room = buf.length - offset - 1; System.arraycopy(lineBuffer, 0, buf, 0, offset); lineBuffer = buf; } buf[offset++] = (char) c; break; } } } catch(IOException ioe) {ioe.printStackTrace();} if ((c == -1) && (offset == 0)) { return null; } return String.copyValueOf(buf, 0, offset); } }现在写MAIN函数执行download 通过 。。 从SERVLET中调用download ,参数也和上面一致 。。下载的文件却是没有数据的及0KB.
这有关吗??
从servlet中访问该类的DOWNLOAD方法下载文件时,没有任何错误,
执行也正常,不过在inputstream那读取远程文件时数据为空显示0字节。
outstream出来当然也一样了。好奇怪。后来想难道是
说实话,我还没看懂你的问题呢!
1 本地通过,那证明对方服务没有任何问题
2 servlet 其实和本地没有区别
3 InputStream 读取为空?你怎么读取的?呵呵!建议你将servlet做成应用,在服务器上单独运行看看。 然后再在web里面调用servlet.分步排查出现问题的原因。
import java.net.*;
import java.util.*;@SuppressWarnings("deprecation")
public class FTP { // FOR INITIAL DEBUGGING: set the variable to "true"
private boolean DEBUG = true; //private static final int CNTRL_PORT = 21;
private Socket csock = null;
private Socket dsock = null;
private DataInputStream dcis;
private PrintStream pos;
// constructor needs servername, username and passwd
public FTP(String server,int port, String user, String pass) {
try {
ftpConnect(server,port);
ftpLogin(user, pass);
} catch(IOException ioe) {ioe.printStackTrace();}
}
public void download(String dir, String file, boolean asc, String dest) throws Exception {
int BUFSIZE = 1000;
byte[] buf = new byte[BUFSIZE];
int i;
if (DEBUG) {
System.out.println("Downloading " + file);
}
ftpSetDir(dir);
ftpSetTransferType(asc);
dsock = ftpGetDataSock();
BufferedInputStream in = new BufferedInputStream(dsock.getInputStream(), BUFSIZE);
FileOutputStream out = new FileOutputStream(dest);
ftpSendCmd("RETR "+file);
while ((i = in.read(buf)) != -1) {
out.write(buf, 0, i);
out.flush();
}
in.close();
out.close();
ftpLogout();
}
private void ftpConnect(String server,int port)
throws IOException {
// Set up socket, control streams, connect to ftp server
// Open socket to server control port 21
csock = new Socket(server, port);
// Open control streams
InputStream cis = csock.getInputStream();
dcis = new DataInputStream(cis);
OutputStream cos = csock.getOutputStream();
pos = new PrintStream(cos); // handle more than one line returned
String reply = dcis.readLine();
String numerals = reply.substring(0, 3);
String hyph_test = reply.substring(3, 4);
String next = null;
if(hyph_test.equals("-")) {
boolean done = false;
while(!done) { // read lines til find "" -> last line
next = dcis.readLine();
if(next.substring(0,3).equals(numerals) &&
next.substring(3, 4).equals(" "))
done = true;
}
} if(numerals.substring(0,3).equals("220")) // ftp server alive
; // System.out.println("Connected to ftp server");
else System.err.println("Error connecting to ftp server.");
}
private Socket ftpGetDataSock()
throws IOException {
// Go to PASV mode, capture server reply, parse for socket setup
// V2.1: generalized port parsing, allows more server variations
String reply = ftpSendCmd("PASV"); // New technique: just find numbers before and after ","!
StringTokenizer st = new StringTokenizer(reply, ",");
String[] parts = new String[6]; // parts, incl. some garbage
int i = 0; // put tokens into String array
while(st.hasMoreElements()) {
// stick pieces of host, port in String array
try {
parts[i] = st.nextToken();
i++;
} catch(NoSuchElementException nope){nope.printStackTrace();}
} // end getting parts of host, port // Get rid of everything before first "," except digits
String[] diggies = new String[3];
for(int j = 0; j < 3; j++) {
// Get 3 characters, inverse order, check if digit/character
diggies[j] = parts[0].substring(parts[0].length() - (j + 1),
parts[0].length() - j); // next: digit or character?
if(!Character.isDigit(diggies[j].charAt(0)))
diggies[j] = "";
}
parts[0] = diggies[2] + diggies[1] + diggies[0];
// Get only the digits after the last ","
String[] porties = new String[3];
for(int k = 0; k < 3; k++) {
// Get 3 characters, in order, check if digit/character
// May be less than 3 characters
if((k + 1) <= parts[5].length())
porties[k] = parts[5].substring(k, k + 1);
else porties[k] = "FOOBAR"; // definitely not a digit!
// next: digit or character?
if(!Character.isDigit(porties[k].charAt(0)))
porties[k] = "";
} // Have to do this one in order, not inverse order
parts[5] = porties[0] + porties[1] + porties[2];
// Get dotted quad IP number first
String ip = parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3]; // Determine port
int port = -1;
try { // Get first part of port, shift by 8 bits.
int big = Integer.parseInt(parts[4]) << 8;
int small = Integer.parseInt(parts[5]);
port = big + small; // port number
} catch(NumberFormatException nfe) {nfe.printStackTrace();}
if((ip != null) && (port != -1))
dsock = new Socket(ip, port);
else throw new IOException();
return dsock;
}
private void ftpLogin(String user, String pass)
throws IOException {
ftpSendCmd("USER "+user);
ftpSendCmd("PASS "+pass);
}
private void ftpLogout() {// logout, close streams
try {
if(DEBUG) System.out.println("sending BYE");
pos.print("BYE" + "\r\n" );
pos.flush();
pos.close();
dcis.close();
csock.close();
dsock.close();
} catch(IOException ioe) {ioe.printStackTrace();}
}
private String ftpSendCmd(String cmd)
throws IOException
{ // This sends a dialog string to the server, returns reply
// V2.0 Updated to parse multi-string responses a la RFC 959
// Prints out only last response string of the lot.
pos.print(cmd + "\r\n" );
String reply = dcis.readLine();
String numerals = reply.substring(0, 3);
String hyph_test = reply.substring(3, 4);
String next = null;
if(hyph_test.equals("-")) {
boolean done = false;
while(!done) { // read lines til find "" -> last line
next = dcis.readLine();
if(next.substring(0,3).equals(numerals) &&
next.substring(3, 4).equals(" "))
done = true;
}
if(DEBUG)
System.out.println("Response to: "+cmd+" was: "+next);
return next;
} else
if(DEBUG)
System.out.println("Response to: "+cmd+" was: "+reply);
return reply;
}
private void ftpSetDir(String dir)
throws IOException {
// cwd to dir
ftpSendCmd("CWD "+dir);
}
private void ftpSetTransferType(boolean asc)
throws IOException {
// set file transfer type
String ftype = (asc? "A" : "I");
ftpSendCmd("TYPE "+ftype);
}
///////////////// private fields ////////////////////
private String getAsString(InputStream is) {
int c=0;
char lineBuffer[]=new char[128], buf[]=lineBuffer;
int room= buf.length, offset=0;
try {
loop: while (true) {
// read chars into a buffer which grows as needed
switch (c = is.read() ) {
case -1: break loop; default: if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0,
buf, 0, offset);
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
} catch(IOException ioe) {ioe.printStackTrace();}
if ((c == -1) && (offset == 0)) {
return null;
}
return String.copyValueOf(buf, 0, offset);
}
}现在写MAIN函数执行download 通过 。。
从SERVLET中调用download ,参数也和上面一致 。。下载的文件却是没有数据的及0KB.