posts - 309, comments - 6940, trackbacks - 0, articles - 3
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

用Java实现FTP批量大文件上传下载(三)

Posted on 2007-10-22 09:45 诗特林 阅读(7748) 评论(4)  编辑  收藏 所属分类: Socket
                                                     用Java实现FTP批量大文件上传下载(三) 
  • 用Java实现FTP批量大文件上传下载(六)--代码及示例下载
  • 用Java实现FTP批量大文件上传下载(五) --运行效果图
  • 用Java实现FTP批量大文件上传下载(四)
  • 用Java实现FTP批量大文件上传下载(三)
  • 用Java实现FTP批量大文件上传下载(二)
  • 用Java实现FTP批量大文件上传下载(一)

  •  

    五、断点续传

    对于熟用QQ的程序员,QQ的断点续传功能应该是印象很深刻的。因为它很实用也很方面。因此,在我们的上传下载过程中,很实现了断点续传的功能。

    其实断点续传的原理很简单,就在上传的过程中,先去服务上进行查找,是否存在此文件,如果存在些文件,则比较服务器上文件的大小与本地文件的大小,如果服务器上的文件比本地的要小,则认为此文件上传过程中应该可以进行断点续传。

    在实现的过程中,RandomAccessFile类变得很有用。此类的实例支持对随机存取文件的读取和写入。随机存取文件的行为类似存储在文件系统中的一个大型字节数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机存取文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法进行设置。

    RandomAccessFile类的skipBytes方法尝试跳过输入的 n 个字节以丢弃跳过的字节。如果从服务器上查得待上传文件的大小n,则采用skipBytes方法可以跳过这n个字节,从而开始从新的地方开始进行断点续传。具体的方法说明可以参见JDK5API说明。

    可以在net.sf.jftp.net. DataConnection类的run方法中,可以看出上传下载中断点续传的实现,代码如下:

    public void run()
        
    {
            
    try
            
    {
            newLine 
    = con.getCRLF();

                
    if(Settings.getFtpPasvMode())
                
    {
                    
    try
                    
    {
                        sock 
    = new Socket(host, port);
                        sock.setSoTimeout(Settings.getSocketTimeout());
                    }

                    
    catch(Exception ex)
                    
    {
                        ok 
    = false;
                        debug(
    "Can't open Socket on port " + port);
                    }

                }

                
    else
                
    {
                    
    //Log.debug("trying new server socket: "+port);
                    try
                    
    {
                        ssock 
    = new ServerSocket(port);
                    }

                    
    catch(Exception ex)
                    
    {
                        ok 
    = false;
                        Log.debug(
    "Can't open ServerSocket on port " + port);
                    }

                }

            }

            
    catch(Exception ex)
            
    {
                debug(ex.toString());
            }


            isThere 
    = true;

            
    boolean ok = true;

            RandomAccessFile fOut 
    = null;
            BufferedOutputStream bOut 
    = null;
            RandomAccessFile fIn 
    = null;

            
    try
            
    {
                
    if(!Settings.getFtpPasvMode())
                
    {
                    
    int retry = 0;

                    
    while((retry++ < 5&& (sock == null))
                    
    {
                        
    try
                        
    {
                            ssock.setSoTimeout(Settings.connectionTimeout);
                            sock 
    = ssock.accept();
                        }

                        
    catch(IOException e)
                        
    {
                            sock 
    = null;
                            debug(
    "Got IOException while trying to open a socket!");

                            
    if(retry == 5)
                            
    {
                                debug(
    "Connection failed, tried 5 times - maybe try a higher timeout in Settings.java");
                            }


                    finished 
    = true;

                            
    throw e;
                        }

                        
    finally
                        
    {
                            ssock.close();
                        }


                        debug(
    "Attempt timed out, retrying");
                    }

                }


                
    if(ok)
                
    {
                    
    byte[] buf = new byte[Settings.bufferSize];
                    start 
    = System.currentTimeMillis();

                    
    int buflen = 0;

                    
    //---------------download,下载----------------------
                    if(type.equals(GET) || type.equals(GETDIR))
                    
    {
                        
    if(!justStream)
                        
    {
                            
    try
                            
    {
                                
    if(resume)
                                
    {
                                    File f 
    = new File(file);
                                    fOut 
    = new RandomAccessFile(file, "rw");
                                    fOut.skipBytes((
    int) f.length());
                                    buflen 
    = (int) f.length();
                                }

                                
    else
                                
    {
                                    
    if(localfile == null)
                                    
    {
                                        localfile 
    = file;
                                    }


                                    File f2 
    = new File(Settings.appHomeDir);
                                    f2.mkdirs();

                                    File f 
    = new File(localfile);

                                    
    if(f.exists())
                                    
    {
                                        f.delete();
                                    }


                                    bOut 
    = new BufferedOutputStream(new FileOutputStream(localfile),
                                                                    Settings.bufferSize);
                                }

                            }

                            
    catch(Exception ex)
                            
    {
                                debug(
    "Can't create outputfile: " + file);
                                ok 
    = false;
                                ex.printStackTrace();
                            }

                        }


                    
                    
    //---------------upload,上传----------------------
                    if(type.equals(PUT) || type.equals(PUTDIR))
                    
    {
                        
    if(in == null)
                        
    {
                            
    try
                            
    {
                                fIn 
    = new RandomAccessFile(file, "r");
                                
                                
    if(resume)
                                
    {
                                    fIn.skipBytes(skiplen);
                                }

                                
                                
    //fIn = new BufferedInputStream(new FileInputStream(file));
                            }

                            
    catch(Exception ex)
                            
    {
                                debug(
    "Can't open inputfile: " + " (" + ex + ")");
                                ok 
    = false;
                            }

                        }

                        
                        
    if(ok)
                        
    {
                            
    try
                            
    {
                                out 
    = new BufferedOutputStream(sock.getOutputStream());
                            }

                            
    catch(Exception ex)
                            
    {
                                ok 
    = false;
                                debug(
    "Can't get OutputStream");
                            }

                            
                            
    if(ok)
                            
    {
                                
    try
                                
    {
                                    
    int len = skiplen;
                                    
    char b;
                                    
                                    
    while(true)
                                    
    {
                                        
    int read;
                                        
                                        
    if(in != null)
                                        
    {
                                            read 
    = in.read(buf);
                                        }

                                        
    else
                                        
    {
                                            read 
    = fIn.read(buf);
                                        }

                                        
                                        len 
    += read;
                                        
                                        
    //System.out.println(file + " " + type+ " " + len + " " + read);
                                        if(read == -1)
                                        
    {
                                            
    break;
                                        }

                                        
                                        
    if(newLine != null
                                        
    {
                                            
    byte[] buf2 = modifyPut(buf, read);
                                            out.write(buf2, 
    0, buf2.length);
                                        }

                                        
    else 
                                        
    {
                                            out.write(buf, 
    0, read);
                                        }

                                        
                                        con.fireProgressUpdate(file, type, len);
                                        
                                        
    if(time())
                                        
    {
                                            
    //   Log.debugSize(len, false, false, file);
                                        }

                                        
                                        
    if(read == StreamTokenizer.TT_EOF)
                                        
    {
                                            
    break;
                                        }

                                    }

                                    
                                    out.flush();
                                    
                                    
    //Log.debugSize(len, false, true, file);
                                }

                                
    catch(IOException ex)
                                
    {
                                    ok 
    = false;
                                    debug(
    "Error: Data connection closed.");
                                    con.fireProgressUpdate(file, FAILED, 
    -1);
                                    ex.printStackTrace();
                                }

                            }

                        }

                    }

                }

            }

            
    catch(IOException ex)
            
    {
                Log.debug(
    "Can't connect socket to ServerSocket");
                ex.printStackTrace();
            }

            
    finally
            
    {
                
    try
                
    {
                    
    if(out != null)
                    
    {
                        out.flush();
                        out.close();
                    }

                }

                
    catch(Exception ex)
                
    {
                    ex.printStackTrace();
                }

                
                
    try
                
    {
                    
    if(bOut != null)
                    
    {
                        bOut.flush();
                        bOut.close();
                    }

                }

                
    catch(Exception ex)
                
    {
                    ex.printStackTrace();
                }

                
                
    try
                
    {
                    
    if(fOut != null)
                    
    {
                        fOut.close();
                    }

                }

                
    catch(Exception ex)
                
    {
                    ex.printStackTrace();
                }

                
                
    try
                
    {
                    
    if(in != null && !justStream)
                    
    {
                        in.close();
                    }

                    
                    
    if(fIn != null)
                    
    {
                        fIn.close();
                    }

                }

                
    catch(Exception ex)
                
    {
                    ex.printStackTrace();
                }

            }

            
            
    try
            
    {
                sock.close();
            }

            
    catch(Exception ex)
            
    {
                debug(ex.toString());
            }

            
            
    if(!Settings.getFtpPasvMode())
            
    {
                
    try
                
    {
                    ssock.close();
                }

                
    catch(Exception ex)
                
    {
                    debug(ex.toString());
                }

            }

            
            finished 
    = true;
            
            
    if(ok)
            
    {
                con.fireProgressUpdate(file, FINISHED, 
    -1);
            }

            
    else
            
    {
                con.fireProgressUpdate(file, FAILED, 
    -1);
            }

        }


    待续
    ......

    评论

    # re: 用Java实现FTP批量大文件上传下载(三)   回复  更多评论   

    2009-05-14 17:35 by qianc
    站长,你好!我现在正在用JFTP做一个项目,现在往FTP服务器上传文件已经可以了,但是在断点续传这一块,还是不能,我是直接引的jftp.jar文件,包里面的DataConnection中的run和你上面说的是一样的,但是断点续传的功能还是没能实现。我自定义的类中执行上传的uploadFiles()中是用的一下代码:BufferedInputStream bufferReader = null;
    try {
    bufferReader = new BufferedInputStream(
    new FileInputStream(current));

    DataConnection conn = new DataConnection(con, 21, "192.168.0.88", current
    .getName(), "PUT", true,19492753, bufferReader);

    conn.reset();
    conn.run();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    我的邮箱qc_future521@163.com

    # re: 用Java实现FTP批量大文件上传下载(三)   回复  更多评论   

    2009-05-14 17:39 by qianc
    执行断点续传是不是就是以上的,我的写法?拜托啦!谢谢!

    # re: 用Java实现FTP批量大文件上传下载(三)   回复  更多评论   

    2012-08-23 14:53 by 博文
    怎么感觉好复杂嗯
    直至用apache的上传工具不好么?
    www.bchome8.com

    # re: 用Java实现FTP批量大文件上传下载(三) [未登录]  回复  更多评论   

    2013-09-30 09:23 by 小白
    718589908@qq.com 拜托楼主了啊!!

    只有注册用户登录后才能发表评论。


    网站导航: