今天做一个FTP下载文件的功能,用的是LOTUS里面写好的
一个类MyFTP.利用socket做的,在本地MAIN函数中执行通过。当我在WEB上
从servlet中访问该类的DOWNLOAD方法下载文件时,没有任何错误,
执行也正常,不过在inputstream那读取远程文件时数据为空显示0字节。
outstream出来当然也一样了。好奇怪。后来想难道是
WEB上socket不起作用 ??请教高手 ??
或者谁有WEB中可以FTP下载文件的例子??

解决方案 »

  1.   

    apache commons > net > FTPClient
      

  2.   

    这好像不行, servlet访问一闪而过,ftp这么短时间可不行,我用过apache的,但是他不会阻塞当前线程。我的做法是开一个线程去做下载的工作。
      

  3.   

    servlet访问一闪而过,ftp这么短时间可不行??
    这有关吗??
      

  4.   

    ,在本地MAIN函数中执行通过。当我在WEB上
    从servlet中访问该类的DOWNLOAD方法下载文件时,没有任何错误,
    执行也正常,不过在inputstream那读取远程文件时数据为空显示0字节。
    outstream出来当然也一样了。好奇怪。后来想难道是 
    说实话,我还没看懂你的问题呢!
    1 本地通过,那证明对方服务没有任何问题
    2 servlet 其实和本地没有区别
    3 InputStream 读取为空?你怎么读取的?呵呵!建议你将servlet做成应用,在服务器上单独运行看看。 然后再在web里面调用servlet.分步排查出现问题的原因。
      

  5.   

    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.