最近做一个项目需要用到FTP上传文件。用到ftpclient这个类。但有时候会出现在日志中显示某个文件上传成,但ftp里找不到的情况。因为我用的多线程,用线程池管理的,线程总数400个。 ftp的封装方法是synchronized 和static的。恩不方便透露公司的代码,所以不好意思 ,看能不能有那位高手给以解答。谢谢

解决方案 »

  1.   

    package nc.ui.doc.doc_007; import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.FileOutputStream; 
    import java.io.IOException; import nc.itf.doc.DocDelegator; 
    import nc.vo.doc.doc_007.DirVO; 
    import nc.vo.pub.BusinessException; 
    import nc.vo.pub.SuperVO; import org.apache.commons.net.ftp.FTPClient; 
    import org.apache.commons.net.ftp.FTPFile; 
    import org.apache.commons.net.ftp.FTPReply; 
    import org.apache.commons.net.ftp.FTP; 
    public class FtpTool { 
    private FTPClient ftp; private String romateDir = ""; private String userName = ""; private String password = ""; private String host = ""; private String port = "21"; public FtpTool(String url) throws IOException { 
    //String url="ftp://user:password@ip:port/ftptest/psd"; 
    int len = url.indexOf("//"); 
    String strTemp = url.substring(len + 2); 
    len = strTemp.indexOf(":"); 
    userName = strTemp.substring(0, len); 
    strTemp = strTemp.substring(len + 1); len = strTemp.indexOf("@"); 
    password = strTemp.substring(0, len); 
    strTemp = strTemp.substring(len + 1); 
    host = ""; 
    len = strTemp.indexOf(":"); 
    if (len < 0)//没有设置端口 

    port = "21"; 
    len = strTemp.indexOf("/"); 
    if (len > -1) { 
    host = strTemp.substring(0, len); 
    strTemp = strTemp.substring(len + 1); 
    } else { 
    strTemp = ""; 

    } else { 
    host = strTemp.substring(0, len); 
    strTemp = strTemp.substring(len + 1); 
    len = strTemp.indexOf("/"); 
    if (len > -1) { 
    port = strTemp.substring(0, len); 
    strTemp = strTemp.substring(len + 1); 
    } else { 
    port = "21"; 
    strTemp = ""; 


    romateDir = strTemp; 
    ftp = new FTPClient(); 
    ftp.connect(host, FormatStringToInt(port)); } public FtpTool(String host, int port) throws IOException { 
    ftp = new FTPClient(); 
    ftp.connect(host, port); 
    } public String login(String username, String password) throws IOException { 
    this.ftp.login(username, password); 
    return this.ftp.getReplyString(); 
    } public String login() throws IOException { 
    this.ftp.login(userName, password); 
    System.out.println("ftp用户: " + userName); 
    System.out.println("ftp密码: " + password); 
    if (!romateDir.equals("")) 
    System.out.println("cd " + romateDir); 
    ftp.changeWorkingDirectory(romateDir); 
    return this.ftp.getReplyString(); 
    } public boolean upload(String pathname, String filename) throws IOException, BusinessException { int reply; 
    int j; 
    String m_sfilename = null; 
    filename = CheckNullString(filename); 
    if (filename.equals("")) 
    return false; 
    reply = ftp.getReplyCode(); 
    if (!FTPReply.isPositiveCompletion(reply)) { 
    ftp.disconnect(); 
    System.out.println("FTP server refused connection."); 
    System.exit(1); 

    FileInputStream is = null; 
    try { 
    File file_in; 
    if (pathname.endsWith(File.separator)) { 
    file_in = new File(pathname + filename); 
    } else { 
    file_in = new File(pathname + File.separator + filename); 

    if (file_in.length() == 0) { 
    System.out.println("上传文件为空!"); 
    return false; 
    }  
        //产生随机数最大到99  
        j = (int)(Math.random()*100); 
        m_sfilename = String.valueOf(j) + ".pdf"; // 生成的文件名 
    is = new FileInputStream(file_in); 
    ftp.setFileType(FTP.BINARY_FILE_TYPE); 
    ftp.storeFile(m_sfilename, is); 
    ftp.logout(); 
    } finally { 
    if (is != null) { 
    is.close(); 


    System.out.println("上传文件成功!"); 
    return true; 

    public boolean delete(String filename) throws IOException { FileInputStream is = null; 
    boolean retValue = false; 
    try { 
    retValue = ftp.deleteFile(filename); 
    ftp.logout(); 
    } finally { 
    if (is != null) { 
    is.close(); 


    return retValue; } public void close() { 
    if (ftp.isConnected()) { 
    try { 
    ftp.disconnect(); 
    } catch (IOException e) { 
    e.printStackTrace(); 


    } public static int FormatStringToInt(String p_String) { 
    int intRe = 0; 
    if (p_String != null) { 
    if (!p_String.trim().equals("")) { 
    try { 
    intRe = Integer.parseInt(p_String); 
    } catch (Exception ex) { } 


    return intRe; 
    } public static String CheckNullString(String p_String) { 
    if (p_String == null) 
    return ""; 
    else 
    return p_String; 
    } public boolean downfile(String pathname, String filename) { String outputFileName = null; 
    boolean retValue = false; 
    try { 
    FTPFile files[] = ftp.listFiles(); 
    int reply = ftp.getReplyCode(); //////////////////////////////////////////////// 
    if (!FTPReply.isPositiveCompletion(reply)) { 
    try { 
    throw new Exception("Unable to get list of files to dowload."); 
    } catch (Exception e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 

    } ///////////////////////////////////////////////////// 
    if (files.length == 0) { 
    System.out.println("No files are available for download."); 
    }else { 
    for (int i=0; i <files.length; i++) { 
    System.out.println("Downloading file "+files[i].getName()+"Size:"+files[i].getSize()); 
    outputFileName = pathname + filename + ".pdf"; 
    //return outputFileName; 
    File f = new File(outputFileName); ////////////////////////////////////////////////////// 
    retValue = ftp.retrieveFile(outputFileName, new FileOutputStream(f)); if (!retValue) { 
    try { 
    throw new Exception ("Downloading of remote file"+files[i].getName()+" failed. ftp.retrieveFile() returned false."); 
    } catch (Exception e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 

    } } 
    } ///////////////////////////////////////////////////////////// 
    } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 

    return retValue; 
    } } 
      

  2.   

    你不如把生成文件名那块逻辑换换
     j = (int)(Math.random()*100); 
     m_sfilename = String.valueOf(j) + ".pdf"; // 生成的文件名 
    不怕重名文件?
      

  3.   

    可能是你的路径出了问题;不是没传上去,而是没传到你想去的地方,所以看起来就没传上去你是synchronize的client,它是不是保存连接状态?
    是不是每次用的时候会重新连接?如果没有,上次用完之后,工作目录是不是改回去了?
    你上传用的是相对路径还是绝对路径?
    你的路径需不需要你自己重新组装,你的目标路径中间有没有特殊的地方,会导致组装得到的路径出问题的等等你给的信息少,暂时也只能想到这些可能,呵呵
      

  4.   

    public synchronized boolean uploadToFtp(String filePath, String remoteFileName)
    {
    try{
    FTPClient f = new FTPClient();
    InetAddress server = InetAddress.getByName(rc.getFtpHost());
    f.connect(server, rc.getFtpPort());
    f.login(rc.getFtpUser(), rc.getFtpPassword());
    log.debug("Reply String: " + f.getReplyString());
    f.setFileType(f.BINARY_FILE_TYPE);
    f.enterLocalPassiveMode();

    log.debug("Reply String: " + f.getReplyString());

    InputStream is = new FileInputStream(filePath);
    boolean retValue = f.storeFile(remoteFileName, is);
    is.close();
    log.debug("retValue " + retValue);
    log.debug("client status  " + f.getStatus());
    log.debug("filenames " + Arrays.toString(f.listNames()));
    f.disconnect();
    log.info(filePath + " successfully uploaded");

    }catch(Exception e){
    log.info( "exception is -->"+e.getStackTrace());
    }
    return retValue;

    }
    这个方法有什么问题么?
      

  5.   

    f.enterLocalPassiveMode();这个好像是需要server支持的,如果ftp server不支持对应的模式,会出现文件上不去,但不会报错,好像。
    如果没特别设置过的server,具体需要用那种模式,我有点记不清了,你可以关注下如果说,你的remoteFileName不包含路径信息,只是一个文件名的话,那f.listNames()能够取到,否则是显示不出上传之后的那个文件的,你debug的时候还不如干脆直接去list那个remoteFileName另外,你最后一句的
    return retValue;
    不会报错?
    貌似那个时候retValue已经不存在了啊,呵呵
      

  6.   

    估计 是路径问题  
    建议
    1、在ftp根路径测试
    2、ftp多个连续操作可能会转换当前文件夹,这个得看程序怎么实现的    public void uploadSingleFile(String filename, String remotePath) throws Exception {
            FTPClient ftpClient = connectServer();
            BufferedInputStream buffIn = null;
            try {
                this.checkRemotePath(ftpClient, remotePath);
    //这个方法 会判断 ftp上是否存在要上传的路径,不存在的话会新建,建议你在上传之前也写一个这个方法
                                buffIn = new BufferedInputStream(new FileInputStream(
                }
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.storeFile(remotePath + "/" + file, buffIn);
            } catch (IOException e) {
                throw new Exception(e);
            } finally {            try {
                    if (buffIn != null) {
                        buffIn.close();
                    }
                } catch (IOException e) {
                    throw new Exception(e);
                }
                closeConnect(ftpClient);
            }
        }
      

  7.   

    他这样每次进入方法都重新建立连接,目录是没问题的,刚连上的时候都会出现在用户的工作目录,除非在server上改过这个用户的工作目录配置。FTP没有目录确实不会自动创建,需要自己去检测跟创建。
      

  8.   

    我这样写,也是不能上传。空文件是可以上传的,如果是有内容的文件就不可以上传了。ftp服务器的端口:2121。而且是一样的代码,换了一台ftp服务器就不行了    public static void uploadnew(FileTypeRequest fileTypeRequest,
                String sNewfName, String path, String strParamName)
                throws Exception
        {
            String strFileName = Common.getCNStr(fileTypeRequest
                    .getFileNameByParam(strParamName));
            
            path = getFullPath(path);
            System.out.println(Common.getFtpServer() + "===" + Common.getFtpPort() + "===" + Common.getFtpUser() + "===" + Common.getFtpPassword() + "===" + path + "===" + sNewfName);
            
            String extend = getExtendName(strFileName);        
            if (extend.length() < 1)
            {
                throw new Exception("上传文件的扩展名无法获得!");
            }
            org.apache.commons.net.ftp.FTPClient cFTPClient = null;
            OutputStream os = null;
            InputStream fis = null;
            try
            {
                System.out.println("init ftpclient");
                cFTPClient = new org.apache.commons.net.ftp.FTPClient();
                System.out.println("connect ftpclient");
                
                cFTPClient.connect(Common.getFtpServer(), Common.getFtpPort());
                
                System.out.println("login user and pass");
                cFTPClient.login(Common.getFtpUser(), Common.getFtpPassword());
                cFTPClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                System.out.println("Connected to " + Common.getFtpServer()
                        + " success.");
                         
                if (path.equalsIgnoreCase("") == false)
                {
                    System.out.println("change directory");
                    cFTPClient.changeWorkingDirectory(path);
                }            
                
                System.out.println("create stream ");
                os = cFTPClient.appendFileStream(sNewfName);
                byte[] bytes = new byte[8192];
                int c = 0;
                // 得到输入的流
                fis = fileTypeRequest.getInputStreamByFileParam(strParamName);
                while ((c = fis.read(bytes)) != -1)
                {
                    os.write(bytes, 0, c);
                }
                
            }
            catch (Exception ex)
            {
                throw new Exception(ex.getMessage());
            }
            finally
            {
                if (fis != null)
                    fis.close();
                if (os != null)
                    os.close();
                if (cFTPClient != null && cFTPClient.isConnected())
                {
                    cFTPClient.logout();
                    System.out.println("logout success");
                    cFTPClient.disconnect();
                    System.out.println("disconnect success");
                }        }
        }