精华内容
下载资源
问答
  • 下载一个电影,普通下载方式utorrent方式,速度为什么这么?原理是什么? 原因是:utorrent方式是将一个电影分成了n块,而上传的人越,你下载速度越快。 举例子:

    下载一个电影,普通下载方式和utorrent方式,速度为什么差这么多?原理是什么?


    原因是:utorrent方式是将一个电影分成了n块,而上传的人越多,你下载速度越快。


    举例子:



    需要搞清楚的一点是,在学校里用utorrent下载东西快的原因,不仅仅是bt下载方式,因为上图我也说了utorrent还是会有速度瓶颈,瓶颈发生在客户端,即下载端的带宽。所以学校之所以下载快,更重要的一个原因是在六维空间上下载东西,使用的是ipv6网。使用ipv6协议的客户端,带宽会很大,即水管很粗,很大。带宽可能到100M/每秒,下载速度峰值能达到100M/每秒。



    既然ipv6带宽可以这么大,那么很多人就想问,我怎么才能使用ipv6呢?那就要看你家安装的网络(就是收你钱,给你装宽带的公司,给你安装的网路),支不支持ipv6了。


    还不赶快去看看,你能不能用ipv6。









    展开全文
  • 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验; 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。 支持...

    需求:

    支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验;

    内网百兆网络上传速度为12MB/S

    服务器内存占用低

    支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。

    支持PC端全平台操作系统,Windows,Linux,Mac

    支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。

    支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同。

    支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留进度。

    支持文件夹结构管理,支持新建文件夹,支持文件夹目录导航

    交互友好,能够及时反馈上传的进度;

    服务端的安全性,不因上传文件功能导致JVM内存溢出影响其他功能使用;

    最大限度利用网络上行带宽,提高上传速度;

     

    分析:

    对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传

    从上传的效率来看,利用多线程并发上传能够达到最大效率。

     

    解决方案:

    文件上传页面的前端可以选择使用一些比较好用的上传组件,例如百度的开源组件WebUploader,泽优软件的up6,这些组件基本能满足文件上传的一些日常所需功能,如异步上传文件,文件夹,拖拽式上传,黏贴上传,上传进度监控,文件缩略图,甚至是大文件断点续传,大文件秒传。

     

    在web项目中上传文件夹现在已经成为了一个主流的需求。在OA,或者企业ERP系统中都有类似的需求。上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便。能够提供更高级的应用支撑。

    数据库配置类DBConfig.java

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.SQLException;

    import org.apache.commons.lang.StringUtils;

    import down2.biz.DnFile;

    import down2.biz.DnFileMySQL;

    import down2.biz.DnFileOracle;

    import down2.biz.DnFileSQL;

     

    /**

     * 数据库配置类

    @author jmzy

    */

    publicclassDBConfig {

        publicStringm_db="oracle";//sql,oracle,mysql

        Stringdriver = "";

        Stringurl = "";

        Stringname = "";

        Stringpass = "";

       

        //sql

        Stringsql_driver= "com.microsoft.sqlserver.jdbc.SQLServerDriver";

        Stringsql_url = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=up6";

        Stringsql_name = "sa";

        Stringsql_pass = "123456";

       

        //mysql

        Stringmysql_driver = "com.mysql.jdbc.Driver";

        Stringmysql_url = "jdbc:mysql://127.0.0.1:3306/up6?user=root&password=123456&characterEncoding=UTF-8";

       

        //oracle数据库配置

        Stringoracle_driver = "oracle.jdbc.driver.OracleDriver";

        Stringoracle_url = "jdbc:oracle:thin:@localhost:1521:orcl";

        Stringoracle_name = "system";

        Stringoracle_pass = "123456";

       

        public DBConfig() {

                   

            if( StringUtils.equals(this.m_db, "sql") )

            {

                this.driver = this.sql_driver;

                this.url = this.sql_url;

                this.name = this.sql_name;

                this.pass = this.sql_pass;

            }

            elseif( StringUtils.equals(this.m_db, "mysql") )

            {

                this.driver = this.mysql_driver;

                this.url = this.mysql_url;

            }

            elseif( StringUtils.equals(this.m_db, "oracle") )

            {

                this.driver = this.oracle_driver;

                this.url = this.oracle_url;

                this.name = this.oracle_name;

                this.pass = this.oracle_pass;

            }

        }

       

        publicDBFile db() {       

            if( StringUtils.equals(this.m_db, "sql") ) returnnewDBFileSQL();

            elseif( StringUtils.equals(this.m_db, "mysql") ) returnnewDBFileMySQL();

            elseif( StringUtils.equals(this.m_db, "oracle") ) returnnewDBFileOracle();

            elsereturnnewDBFile();

        }

       

        publicDnFile down() {

            if( StringUtils.equals(this.m_db, "sql") ) returnnewDnFileSQL();

            elseif( StringUtils.equals(this.m_db, "mysql") ) returnnewDnFileMySQL();

            elseif( StringUtils.equals(this.m_db, "oracle") ) returnnewDnFileOracle();

            elsereturnnewDnFile();      

        }

        public Connection getCon()

        {

            Connection con = null;

           

            try

            {

                Class.forName(this.driver).newInstance();//加载驱动。

                if (StringUtils.equals(this.m_db, "mysql")) con = DriverManager.getConnection(this.url);

                elsecon = DriverManager.getConnection(this.url,this.name,this.pass);

            }

            catch (SQLExceptione)

            {

                // TODO Auto-generated catch block

                e.printStackTrace();

            } catch (InstantiationExceptione) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            } catch (IllegalAccessExceptione) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            } catch (ClassNotFoundExceptione) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            returncon;    

        }

    }

     

    该项目核心就是文件分块上传。前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题。

    * 如何分片;

    * 如何合成一个文件;

    * 中断了从哪个分片开始。

    如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子。但是因为时间的关系还有工作的关系,我只能罢休了。最后我选择了百度的WebUploader来实现前端所需。

    如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的。刚开始的时候,我是采用了前端生成了唯一uuid来做文件的标志,在每个分片请求上带上。不过后来在做秒传的时候我放弃了,采用了Md5来维护分块和文件关系。

    在服务端合并文件,和记录分块的问题,在这方面其实行业已经给了很好的解决方案了。参考迅雷,你会发现,每次下载中的时候,都会有两个文件,一个文件主体,另外一个就是文件临时文件,临时文件存储着每个分块对应字节位的状态。

    这些都是需要前后端密切联系才能做好,前端需要根据固定大小对文件进行分片,并且请求中要带上分片序号和大小。前端发送请求顺利到达后台后,服务器只需要按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件即可。

    为了便于开发,我 将服务端的业务逻辑进行了如下划分,分成初始化,块处理,文件上传完毕等。

    服务端的业务逻辑模块如下

     

     

    功能分析:

    文件夹生成模块

     

    文件夹上传完毕后由服务端进行扫描代码如下

     

    分块上传,分块处理逻辑应该是最简单的逻辑了,up6已经将文件进行了分块,并且对每个分块数据进行了标识,这些标识包括文件块的索引,大小,偏移,文件MD5,文件块MD5(需要开启)等信息,服务端在接收这些信息后便可以非常方便的进行处理了。比如将块数据保存到分布式存储系统中

    分块上传可以说是我们整个项目的基础,像断点续传、暂停这些都是需要用到分块。

    分块这块相对来说比较简单。前端是采用了webuploader,分块等基础功能已经封装起来,使用方便。

    借助webUpload提供给我们的文件API,前端就显得异常简单。

    前台HTML模板

     

    分则必合。把大文件分片了,但是分片了就没有原本文件功能,所以我们要把分片合成为原本的文件。我们只需要把分片按原本位置写入到文件中去。因为前面原理那一部我们已经讲到了,我们知道分块大小和分块序号,我就可以知道该分块在文件中的起始位置。所以这里使用RandomAccessFile是明智的,RandomAccessFile能在文件里面前后移动。但是在andomAccessFile的绝大多数功能,已经被JDK1.4的NIO的“内存映射文件(memory-mapped files)”取代了。我在该项目中分别写了使用RandomAccessFile与MappedByteBuffer来合成文件。分别对应的方法是uploadFileRandomAccessFile和uploadFileByMappedByteBuffer。两个方法代码如下。

    秒传功能

    服务端逻辑

    秒传功能,相信大家都体现过了,网盘上传的时候,发现上传的文件秒传了。其实原理稍微有研究过的同学应该知道,其实就是检验文件MD5,记录下上传到系统的文件的MD5,在一个文件上传前先获取文件内容MD5值或者部分取值MD5,然后在匹配系统上的数据。

    Breakpoint-http实现秒传原理,客户端选择文件之后,点击上传的时候触发获取文件MD5值,获取MD5后调用系统一个接口(/index/checkFileMd5),查询该MD5是否已经存在(我在该项目中用redis来存储数据,用文件MD5值来作key,value是文件存储的地址。)接口返回检查状态,然后再进行下一步的操作。相信大家看代码就能明白了。

    嗯,前端的MD5取值也是用了webuploader自带的功能,这还是个不错的工具。

    控件计算完文件MD5后会触发md5_complete事件,并传值md5,开发者只需要处理这个事件即可,

     

    断点续传

    up6已经自动对断点续传进行了处理,不需要开发都再进行单独的处理。

    在f_post.jsp中接收这些参数,并进行处理,开发者只需要关注业务逻辑,不需要关注其它的方面。

     

    断点续传,就是在文件上传的过程中发生了中断,人为因素(暂停)或者不可抗力(断网或者网络差)导致了文件上传到一半失败了。然后在环境恢复的时候,重新上传该文件,而不至于是从新开始上传的。

    前面也已经讲过,断点续传的功能是基于分块上传来实现的,把一个大文件分成很多个小块,服务端能够把每个上传成功的分块都落地下来,客户端在上传文件开始时调用接口快速验证,条件选择跳过某个分块。

    实现原理,就是在每个文件上传前,就获取到文件MD5取值,在上传文件前调用接口(/index/checkFileMd5,没错也是秒传的检验接口)如果获取的文件状态是未完成,则返回所有的还没上传的分块的编号,然后前端进行条件筛算出哪些没上传的分块,然后进行上传。

    当接收到文件块后就可以直接写入到服务器的文件中

    这是文件夹上传完后的效果

    这是文件夹上传完后在服务端的存储结构

    参考文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

    展开全文
  • ssh实现上传和下载

    千次阅读 2008-05-21 09:41:00
    文件的上传和下载在J2EE编程已经是一个非常古老的话题了,也许您马上就能掰着指头数出好几个著名的大件:如SmartUpload、Apache的FileUpload。但如果您的项目是构建在Struts+Spring+Hibernate(以下称SSH)框架上的...
    文件的上传和下载在J2EE编程已经是一个非常古老的话题了,也许您马上就能掰着指头数出好几个著名的大件:如SmartUpload、Apache的FileUpload。但如果您的项目是构建在Struts+Spring+Hibernate(以下称SSH)框架上的,这些大件就显得笨重而沧桑了,SSH提供了一个简捷方便的文件上传下载的方案,我们只需要通过一些配置并辅以少量的代码就可以完好解决这个问题了。

      本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本:

      ·Struts 1.2

      ·Spring 1.2.5

      ·Hibernate 3.0

      本文选用的数据库为Oracle 9i,当然你可以在不改动代码的情况下,通过配置文件的调整将其移植到任何具有Blob字段类型的数据库上,如MySQL,SQLServer等。

      总体实现

      上传文件保存到T_FILE表中,T_FILE表结构如下:


    图 1 T_FILE表结构

      其中:

      ·FILE_ID:文件ID,32个字符,用Hibernate的uuid.hex算法生成。

      ·FILE_NAME:文件名。

      ·FILE_CONTENT:文件内容,对应Oracle的Blob类型。

      ·REMARK:文件备注。

      文件数据存储在Blob类型的FILE_CONTENT表字段上,在Spring中采用OracleLobHandler来处理Lob字段(包括Clob和Blob),由于在程序中不需要引用到oracle数据驱动程序的具体类且屏蔽了不同数据库处理Lob字段方法上的差别,从而撤除程序在多数据库移植上的樊篱。

      1.首先数据表中的Blob字段在Java领域对象中声明为byte[]类型,而非java.sql.Blob类型。

      2.数据表Blob字段在Hibernate持久化映射文件中的type为org.springframework.orm.hibernate3.support.BlobByteArrayType,即Spring所提供的用户自定义的类型,而非java.sql.Blob。

      3.在Spring中使用org.springframework.jdbc.support.lob.OracleLobHandler处理Oracle数据库的Blob类型字段。

      通过这样的设置和配置,我们就可以象持久化表的一般字段类型一样处理Blob字段了。

      以上是Spring+Hibernate将文件二进制数据持久化到数据库的解决方案,而Struts通过将表单中file类型的组件映射为ActionForm中类型为org.apache.struts.upload. FormFile的属性来获取表单提交的文件数据。

      综上所述,我们可以通过图 2,描绘出SSH处理文件上传的方案:


    图 2 SSH处理文件上传技术方案

      文件上传的页面如图 3所示:


    图 3 文件上传页面

      文件下载的页面如图 4所示:


    图 4 文件下载页面

      该工程的资源结构如图 5所示:


    图 5 工程资源结构

      工程的类按SSH的层次结构划分为数据持久层、业务层和Web层;WEB-INF下的applicationContext.xml为Spring的配置文件,struts-config.xml为Struts的配置文件,file-upload.jsp为文件上传页面,file-list.jsp为文件列表页面。

      本文后面的章节将从数据持久层->业务层->Web层的开发顺序,逐层讲解文件上传下载的开发过程。
    数据持久层

      1、领域对象及映射文件

      您可以使用Hibernate Middlegen、HIbernate Tools、Hibernate Syhchronizer等工具或手工的方式,编写Hibernate的领域对象和映射文件。其中对应T_FILE表的领域对象Tfile.java为:

      代码 1 领域对象Tfile

    1. package sshfile.model;
    2. public class Tfile
    3.{
    4. private String fileId;
    5. private String fileName;
    6. private byte[] fileContent;
    7. private String remark;
    8. …//getter and setter
    9. }

      特别需要注意的是:数据库表为Blob类型的字段在Tfile中的fileContent类型为byte[]。Tfile的Hibernate映射文件Tfile.hbm.xml放在Tfile .java类文件的相同目录下:

      代码 2 领域对象映射文件

    1. <?xml version="1.0"?>
    2. <!DOCTYPE hibernate-mapping PUBLIC
    3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
    5. <hibernate-mapping>
    6. <class name="sshfile.model.Tfile" table="T_FILE">
    7. <id name="fileId" type="java.lang.String" column="FILE_ID">
    8. <generator class="uuid.hex"/>
    9. </id>
    10. <property name="fileContent"
    11. type="org.springframework.orm.hibernate3.support.BlobByteArrayType"
    12. column="FILE_CONTENT" lazy="true"/>
    13. …//其它一般字段的映射
    14. </class>
    15. </hibernate-mapping>

      fileContent字段映射为Spring所提供的BlobByteArrayType类型,BlobByteArrayType是用户自定义的数据类型,它实现了Hibernate 的org.hibernate.usertype.UserType接口。BlobByteArrayType使用从sessionFactory获取的Lob操作句柄lobHandler将byte[]的数据保存到Blob数据库字段中。这样,我们就再没有必要通过硬编码的方式,先insert然后再update来完成Blob类型数据的持久化,这个原来难伺候的老爷终于被平民化了。关于lobHandler的配置请见本文后面的内容。

      此外lazy="true"说明地返回整个Tfile对象时,并不返回fileContent这个字段的数据,只有在显式调用tfile.getFileContent()方法时才真正从数据库中获取fileContent的数据。这是Hibernate3引入的新特性,对于包含重量级大数据的表字段,这种抽取方式提高了对大字段操作的灵活性,否则加载Tfile对象的结果集时如果总是返回fileContent,这种批量的数据抽取将可以引起数据库的"洪泛效应"。

      2、DAO编写和配置

      Spring强调面向接口编程,所以我们将所有对Tfile的数据操作的方法定义在TfileDAO接口中,这些接口方法分别是:

      ·findByFildId(String fileId)

      ·save(Tfile tfile)

      ·List findAll()

      TfileDAOHibernate提供了对TfileDAO接口基于Hibernate的实现,如代码 3所示:

      代码 3 基于Hibernate 的fileDAO实现类

    1. package sshfile.dao;
    2.
    3. import sshfile.model.*;
    4. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
    5. import java.util.List;
    6.
    7. public class TfileDAOHibernate
    8. extends HibernateDaoSupport implements TfileDAO
    9. {
    10. public Tfile findByFildId(String fileId)
    11. {
    12. return (Tfile) getHibernateTemplate().get(Tfile.class, fileId);
    13. }
    14. public void save(Tfile tfile)
    15. {
    16. getHibernateTemplate().save(tfile);
    17. getHibernateTemplate().flush();
    18. }
    19. public List findAll()
    20. {
    21. return getHibernateTemplate().loadAll(Tfile.class);
    22. }
    23. }

      TfileDAOHibernate通过扩展Spring提供的Hibernate支持类HibernateDaoSupport而建立,HibernateDaoSupport封装了HibernateTemplate,而HibernateTemplate封装了Hibernate所提供几乎所有的的数据操作方法,如execute(HibernateCallback action),load(Class entityClass, Serializable id),save(final Object entity)等等。

      所以我们的DAO只需要简单地调用父类的HibernateTemplate就可以完成几乎所有的数据库操作了。

      由于Spring通过代理Hibernate完成数据层的操作,所以原Hibernate的配置文件hibernate.cfg.xml的信息也转移到Spring的配置文件中:

      代码 4 Spring中有关Hibernate的配置信息

    1. <beans>
    2. <!-- 数据源的配置 //-->
    3. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    4. destroy-method="close">
    5. <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    6. <property name="url" value="jdbc:oracle:thin:@localhost:1521:ora9i"/>
    7. <property name="username" value="test"/>
    8. <property name="password" value="test"/>
    9. </bean>
    10. <!-- Hibernate会话工厂配置 //-->
    11. <bean id="sessionFactory"
    12. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    13. <property name="dataSource" ref="dataSource"/>
    14. <property name="mappingDirectoryLocations">
    15. <list>
    16. <value>classpath:/sshfile/model</value>
    17. </list>
    18. </property>
    19. <property name="hibernateProperties">
    20. <props>
    21. <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
    22. <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
    23. </props>
    24. </property>
    25. </bean>
    26. <!-- Hibernate 模板//-->
    27. <bean id="hibernateTemplate"
    28. class="org.springframework.orm.hibernate3.HibernateTemplate">
    29. <property name="sessionFactory" ref="sessionFactory"/>
    30. </bean>
    31. <!--DAO配置 //-->
    32. <bean id="tfileDAO" class="sshfile.dao.TfileDAOHibernate">
    33. <property name="hibernateTemplate" ref="hibernateTemplate" />
    34. </bean>
    35. …
    36. </beans>

      第3~9行定义了一个数据源,其实现类是apache的BasicDataSource,第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值对设置了Hibernate所需的属性。

      其中第16行通过类路径的映射方式,将sshfile.model类包目录下的所有领域对象的映射文件装载进来,在本文的例子里,它将装载进Tfile.hbm.xml映射文件。如果有多个映射文件需要声明,使用类路径映射方式显然比直接单独指定映射文件名的方式要简便。

      第27~30行定义了Spring代理Hibernate数据操作的HibernateTemplate模板,而第32~34行将该模板注入到tfileDAO中。

      需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,需要根据您所选用Hibernate版本进行正确选择。

      3、Lob字段处理的配置

      我们前面已经指出Oracle的Lob字段和一般类型的字段在操作上有一个明显的区别--那就是你必须首先通过Oracle的empty_blob()/empty_clob()初始化Lob字段,然后获取该字段的引用,通过这个引用更改其值。所以要完成对Lob字段的操作,Hibernate必须执行两步数据库访问操作,先Insert再Update。

      使用BlobByteArrayType字段类型后,为什么我们就可以象一般的字段类型一样操作Blob字段呢?可以确定的一点是:BlobByteArrayType不可能逾越Blob天生的操作方式,原来是BlobByteArrayType数据类型本身具体数据访问的功能,它通过LobHandler将两次数据访问的动作隐藏起来,使Blob字段的操作在表现上和其他一般字段业类型无异,所以LobHandler即是那个"苦了我一个,幸福十亿人"的那位幕后英雄。

      LobHandler必须注入到Hibernate会话工厂sessionFactory中,因为sessionFactory负责产生与数据库交互的Session。LobHandler的配置如代码 5所示:

      代码 5 Lob字段的处理句柄配置

    1. <beans>
    2. …
    3. <bean id="nativeJdbcExtractor"
    4. class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
    5. lazy-init="true"/>
    6. <bean id="lobHandler"
    7. class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
    8. <property name="nativeJdbcExtractor">
    9. <ref local="nativeJdbcExtractor"/>
    10. </property>
    11. </bean>
    12. …
    13. </beans>

      首先,必须定义一个能够从连接池中抽取出本地数据库JDBC对象(如OracleConnection,OracleResultSet等)的抽取器:nativeJdbcExtractor,这样才可以执行一些特定数据库的操作。对于那些仅封装了Connection而未包括Statement的简单数据连接池,SimpleNativeJdbcExtractor是效率最高的抽取器实现类,但具体到apache的BasicDataSource连接池,它封装了所有JDBC的对象,这时就需要使用CommonsDbcpNativeJdbcExtractor了。Spring针对几个著名的Web服务器的数据源提供了相应的JDBC抽取器:

      ·WebLogic:WebLogicNativeJdbcExtractor

      ·WebSphere:WebSphereNativeJdbcExtractor

      ·JBoss:JBossNativeJdbcExtractor

      在定义了JDBC抽取器后,再定义lobHandler。Spring 1.2.5提供了两个lobHandler:

      ·DefaultLobHandler:适用于大部分的数据库,如SqlServer,MySQL,对Oracle 10g也适用,但不适用于Oracle 9i(看来Oracle 9i确实是个怪胎,谁叫Oracle 公司自己都说Oracle 9i是一个过渡性的产品呢)。

      ·OracleLobHandler:适用于Oracle 9i和Oracle 10g。

      由于我们的数据库是Oracle9i,所以使用OracleLobHandler。

      在配置完LobHandler后, 还需要将其注入到sessionFactory的Bean中,下面是调用后的sessionFactory Bean的配置:

      代码 6 将lobHandler注入到sessionFactory中的配置

    1. <beans>
    2. …
    3. <bean id="sessionFactory"
    4. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    5. <property name="dataSource" ref="dataSource"/>
    6. <!-- 为处理Blob类型字段的句柄声明 //-->
    7. <property name="lobHandler" ref="lobHandler"/>
    8. …
    9. </bean>
    10. …
    11. </beans>

      如第7所示,通过sessionFactory的lobHandler属性进行注入。
    业务层

      1、业务层接口

      "面向接口而非面向类编程"是Spring不遗余力所推荐的编程原则,这条原则也已经为大部开发者所接受;此外,JDK的动态代理只对接口有效,否则必须使用CGLIB生成目标类的子类。我们依从于Spring的倡导为业务类定义一个接口:

      代码 7 业务层操作接口

    1. public interface FileService
    2. {
    3. void save(FileActionForm fileForm);//将提交的上传文件保存到数据表中
    4. List getAllFile();//得到T_FILE所示记录
    5. void write(OutputStream os,String fileId);//将某个文件的文件数据写出到输出流中
    6. String getFileName(String fileId);//获取文件名
    7. }

      其中save(FileActionForm fileForm)方法,将封装在fileForm中的上传文件保存到数据库中,这里我们使用FileActionForm作为方法入参,FileActionForm是Web层的表单数据对象,它封装了提交表单的数据。将FileActionForm直接作为业务层的接口入参,相当于将Web层传播到业务层中去,即将业务层绑定在特定的Web层实现技术中,按照分层模型学院派的观点,这是一种反模块化的设计,但在"一般"的业务系统并无需提供多种UI界面,系统Web层将来切换到另一种实现技术的可能性也微乎其微,所以笔者觉得没有必要为了这个业务层完全独立于调用层的过高目标而去搞一个额外的隔离层,浪费了原材料不说,还将系统搞得过于复杂,相比于其它原则,"简单"始终是最大的一条原则。

      getAllFile()负责获取T_FILE表所有记录,以便在网页上显示出来。

      而getFileName(String fileId)和write(OutputStream os,String fileId)则用于下载某个特定的文件。具体的调用是将Web层将response.getOutputStream()传给write(OutputStream os,String fileId)接口,业务层直接将文件数据输出到这个响应流中。具体实现请参见错误!未找到引用源。节下载文件部分。

      2、业务层接口实现类

      FileService的实现类为FileServiceImpl,其中save(FileActionForm fileForm)的实现如下所示:

      代码 8 业务接口实现类之save()

    1. …
    2. public class FileServiceImpl
    3. implements FileService
    4. {
    5. private TfileDAO tfileDAO;
    6. public void save(FileActionForm fileForm)
    7. {
    8. Tfile tfile = new Tfile();
    9. try
    10. {
    11. tfile.setFileContent(fileForm.getFileContent().getFileData());
    12. }
    13. catch (FileNotFoundException ex)
    14. {
    15. throw new RuntimeException(ex);
    16. }
    17. catch (IOException ex)
    18. {
    19. throw new RuntimeException(ex);
    20. }
    21. tfile.setFileName(fileForm.getFileContent().getFileName());
    22. tfile.setRemark(fileForm.getRemark());
    23. tfileDAO.save(tfile);
    24. }
    25. …
    26. }

      在save(FileActionForm fileForm)方法里,完成两个步骤:

      其一,象在水桶间倒水一样,将FileActionForm对象中的数据倒入到Tfile对象中;

      其二,调用TfileDAO保存数据。

      需要特别注意的是代码的第11行,FileActionForm的fileContent属性为org.apache.struts.upload.FormFile类型,FormFile提供了一个方便的方法getFileData(),即可获取文件的二进制数据。通过解读FormFile接口实现类DiskFile的原码,我们可能知道FormFile本身并不缓存文件的数据,只有实际调用getFileData()时,才从磁盘文件输入流中获取数据。由于FormFile使用流读取方式获取数据,本身没有缓存文件的所有数据,所以对于上传超大体积的文件,也是没有问题的;但是,由于数据持久层的Tfile使用byte[]来缓存文件的数据,所以并不适合处理超大体积的文件(如100M),对于超大体积的文件,依然需要使用java.sql.Blob类型以常规流操作的方式来处理。

      此外,通过FileForm的getFileName()方法就可以获得上传文件的文件名,如第21行代码所示。

      write(OutputStream os,String fileId)方法的实现,如代码 9所示:

      代码 9 业务接口实现类之write()

    1. …
    2. public class FileServiceImpl
    3. implements FileService
    4. {
    5.
    6. public void write(OutputStream os, String fileId)
    7. {
    8. Tfile tfile = tfileDAO.findByFildId(fileId);
    9. try
    10. {
    11. os.write(tfile.getFileContent());
    12. os.flush();
    13. }
    14. catch (IOException ex)
    15. {
    16. throw new RuntimeException(ex);
    17. }
    18. }
    19. …
    20. }

      write(OutputStream os,String fileId)也简单地分为两个操作步骤,首先,根据fileId加载表记录,然后将fileContent写入到输出流中。

      3、Spring事务配置

      下面,我们来看如何在Spring配置文件中为FileService配置声明性的事务

    1. <beans>
    2. …
    3. <bean id="transactionManager"
    4. class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    5. <property name="sessionFactory" ref="sessionFactory"/>
    6. </bean>
    7. <!-- 事务处理的AOP配置 //-->
    8. <bean id="txProxyTemplate" abstract="true"
    9. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    10. <property name="transactionManager" ref="transactionManager"/>
    11. <property name="transactionAttributes">
    12. <props>
    13. <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    14. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    15. <prop key="save">PROPAGATION_REQUIRED</prop>
    16. <prop key="write">PROPAGATION_REQUIRED,readOnly</prop>
    17. </props>
    18. </property>
    19. </bean>
    20. <bean id="fileService" parent="txProxyTemplate">
    21. <property name="target">
    22. <bean class="sshfile.service.FileServiceImpl">
    23. <property name="tfileDAO" ref="tfileDAO"/>
    24. </bean>
    25. </property>
    26. </bean>
    27. </beans>

      Spring的事务配置包括两个部分:

      其一,定义事务管理器transactionManager,使用HibernateTransactionManager实现事务管理;

      其二,对各个业务接口进行定义,其实txProxyTemplate和fileService是父子节点的关系,本来可以将txProxyTemplate定义的内容合并到fileService中一起定义,由于我们的系统仅有一个业务接口需要定义,所以将其定义的一部分抽象到父节点txProxyTemplate中意义确实不大,但是对于真实的系统,往往拥有为数众多的业务接口需要定义,将这些业务接口定义内容的共同部分抽取到一个父节点中,然后在子节点中通过parent进行关联,就可以大大简化业务接口的配置了。

      父节点txProxyTemplate注入了事务管理器,此外还定义了业务接口事务管理的方法(允许通过通配符的方式进行匹配声明,如前两个接口方法),有些接口方法仅对数据进行读操作,而另一些接口方法需要涉及到数据的更改。对于前者,可以通过readOnly标识出来,这样有利于操作性能的提高,需要注意的是由于父类节点定义的Bean仅是子节点配置信息的抽象,并不能具体实现化一个Bean对象,所以需要特别标注为abstract="true",如第8行所示。

      fileService作为一个目标类被注入到事务代理器中,而fileService实现类所需要的tfileDAO实例,通过引用3.2节中定义的tfileDAO Bean注入。
    Web层实现

      1、Web层的构件和交互流程

      Web层包括主要3个功能:

      ·上传文件。

      ·列出所有已经上传的文件列表,以供点击下载。

      ·下载文件。

      Web层实现构件包括与2个JSP页面,1个ActionForm及一个Action:

      ·file-upload.jsp:上传文件的页面。

      ·file-list.jsp:已经上传文件的列表页面。

      ·FileActionForm:file-upload.jsp页面表单对应的ActionForm。

      ·FileAction:继承org.apache.struts.actions.DispatchAction的Action,这样这个Action就可以通过一个URL参数区分中响应不同的请求。

      Web层的这些构件的交互流程如图 6所示:


    图 6 Web层Struts流程图

      其中,在执行文件上传的请求时,FileAction在执行文件上传后,forward到loadAllFile出口中,loadAllFile加载数据库中所有已经上传的记录,然后forward到名为fileListPage的出口中,调用file-list.jsp页面显示已经上传的记录。

      2、FileAction功能

      Struts 1.0的Action有一个弱项:一个Action只能处理一种请求,Struts 1.1中引入了一个DispatchAction,允许通过URL参数指定调用Action中的某个方法,如http://yourwebsite/fileAction.do?method=upload即调用FileAction中的upload方法。通过这种方式,我们就可以将一些相关的请求集中到一个Action当中编写,而没有必要为某个请求操作编写一个Action类。但是参数名是要在struts-config.xml中配置的:

    1. <struts-config>
    2. <form-beans>
    3. <form-bean name="fileActionForm" type="sshfile.web.FileActionForm" />
    4. </form-beans>
    5. <action-mappings>
    6. <action name="fileActionForm" parameter="method" path="/fileAction"
    7. type="sshfile.web.FileAction">
    8. <forward name="fileListPage" path="/file-list.jsp" />
    9. <forward name="loadAllFile" path="/fileAction.do?method=listAllFile" />
    10. </action>
    11. </action-mappings>
    12. </struts-config>

      第6行的parameter="method"指定了承载方法名的参数,第9行中,我们还配置了一个调用FileAction不同方法的Action出口。

      FileAction共有3个请求响应的方法,它们分别是:

      ·upload(…):处理上传文件的请求。

      ·listAllFile(…):处理加载数据库表中所有记录的请求。

      ·download(…):处理下载文件的请求。

      下面我们分别对这3个请求处理方法进行讲解。

      2.1 上传文件

      上传文件的请求处理方法非常简单,简之言之,就是从Spring容器中获取业务层处理类FileService,调用其save(FileActionForm form)方法上传文件,如下所示:

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. //将上传文件保存到数据库中
    5. public ActionForward upload(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. {
    9. FileActionForm fileForm = (FileActionForm) form;
    10. FileService fileService = getFileService();
    11. fileService.save(fileForm);
    12. return mapping.findForward("loadAllFile");
    13. }
    14. //从Spring容器中获取FileService对象
    15. private FileService getFileService()
    16. {
    17. ApplicationContext appContext = WebApplicationContextUtils.
    18. getWebApplicationContext(this.getServlet().getServletContext());
    19. return (FileService) appContext.getBean("fileService");
    20. }
    21. …
    22. }

      由于FileAction其它两个请求处理方法也需要从Spring容器中获取FileService实例,所以我们特别提供了一个getFileService()方法(第15~21行)。重构的一条原则就是:"发现代码中有重复的表达式,将其提取为一个变量;发现类中有重复的代码段,将其提取为一个方法;发现不同类中有相同的方法,将其提取为一个类"。在真实的系统中,往往拥有多个Action和多个Service类,这时一个比较好的设置思路是,提供一个获取所有Service实现对象的工具类,这样就可以将Spring 的Service配置信息屏蔽在一个类中,否则Service的配置名字散落在程序各处,维护性是很差的。

      2.2 列出所有已经上传的文件

      listAllFile方法调用Servie层方法加载T_FILE表中所有记录,并将其保存在Request域中,然后forward到列表页面中:

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. …
    5. public ActionForward listAllFile(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. throws ModuleException
    9. {
    10. FileService fileService = getFileService();
    11. List fileList = fileService.getAllFile();
    12. request.setAttribute("fileList",fileList);
    13. return mapping.findForward("fileListPage");
    14. }
    15. }

      file-list.jsp页面使用Struts标签展示出保存在Request域中的记录:

    1. <%@page contentType="text/html; charset=GBK"%>
    2. <%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
    3. <%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
    4. <html>
    5. <head>
    6. <title>file-download</title>
    7. </head>
    8. <body bgcolor="#ffffff">
    9. <ol>
    10. <logic:iterate id="item" name="fileList" scope="request">
    11. <li>
    12. <a href='fileAction.do?method=download&fileId=
    13. <bean:write name="item"property="fileId"/>'>
    14. <bean:write name="item" property="fileName"/>
    15. </a>
    16. </li>
    17. </logic:iterate>
    18. </ol>
    19. </body>
    20. </html>

      展现页面的每条记录挂接着一个链接地址,形如:fileAction.do?method=download&fileId=xxx,method参数指定了这个请求由FileAction的download方法来响应,fileId指定了记录的主键。

      由于在FileActionForm中,我们定义了fileId的属性,所以在download响应方法中,我们将可以从FileActionForm中取得fileId的值。这里涉及到一个处理多个请求Action所对应的ActionForm的设计问题,由于原来的Action只能对应一个请求,那么原来的ActionForm非常简单,它仅需要将这个请求的参数项作为其属性就可以了,但现在一个Action对应多个请求,每个请求所对应的参数项是不一样的,此时的ActionForm的属性就必须是多请求参数项的并集了。所以,除了文件上传请求所对应的fileContent和remark属性外还包括文件下载的fileId属性:


    图 7 FileActionForm

      当然这样会造成属性的冗余,比如在文件上传的请求中,只会用到fileContent和remark属性,而在文件下载的请求时,只会使用到fileId属性。但这种冗余是会带来好处的--它使得一个Action可以处理多个请求。

      2.3 下载文件

      在列表页面中点击一个文件下载,其请求由FileAction的download方法来响应,download方法调用业务层的FileService方法,获取文件数据并写出到response的响应流中。通过合理设置HTTP响应头参数,将响应流在客户端表现为一个下载文件对话框,其代码如下所示:

      代码 10 业务接口实现类之download

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. …
    5. public ActionForward download(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. throws ModuleException
    9. {
    10. FileActionForm fileForm = (FileActionForm) form;
    11. FileService fileService = getFileService();
    12. String fileName = fileService.getFileName(fileForm.getFileId());
    13. try
    14. {
    15. response.setContentType("application/x-msdownload");
    16. response.setHeader("Content-Disposition",
    17. "attachment;" + " filename="+
    18. new String(fileName.getBytes(), "ISO-8859-1"));
    19. fileService.write(response.getOutputStream(), fileForm.getFileId());
    20. }
    21. catch (Exception e)
    22. {
    23. throw new ModuleException(e.getMessage());
    24. }
    25. return null;
    26. }
    27. }

      第15~18行,设置HTTP响应头,将响应类型设置为application/x-msdownload MIME类型,则响应流在IE中将弹出一个文件下载的对话框,如图 4所示。IE所支持的MIME类型多达26种,您可以通过这个网址查看其他的MIME类型:

    http://msdn.microsoft.com/workshop/networking/moniker/overview/appendix_a.asp。

      如果下载文件的文件名含有中文字符,如果不对其进行硬编码,如第18行所示,客户文件下载对话框中出现的文件名将会发生乱码。
    第19行代码获得response的输出流,作为FileServie write(OutputStream os,String fileId)的入参,这样文件的内容将写到response的输出流中。

      3、web.xml文件的配置

      Spring容器在何时启动呢?我可以在Web容器初始化来执行启动Spring容器的操作,Spring提供了两种方式启动的方法:

      ·通过org.springframework.web.context .ContextLoaderListener容器监听器,在Web容器初始化时触发初始化Spring容器,在web.xml中通过<listener></listener>对其进行配置。

      ·通过Servlet org.springframework.web.context.ContextLoaderServlet,将其配置为自动启动的Servlet,在Web容器初始化时,通过这个Servlet启动Spring容器。

      在初始化Spring容器之前,必须先初始化log4J的引擎,Spring也提供了容器监听器和自动启动Servlet两种方式对log4J引擎进行初始化:

      ·org.springframework.web.util .Log4jConfigListener

      ·org.springframework.web.util.Log4jConfigServlet

      下面我们来说明如何配置web.xml启动Spring容器:

      代码 11 web.xml中对应Spring的配置内容

    1. <web-app>
    2. <context-param>
    3. <param-name>contextConfigLocation</param-name>
    4. <param-value>/WEB-INF/applicationContext.xml</param-value>
    5. </context-param>
    6. <context-param>
    7. <param-name>log4jConfigLocation</param-name>
    8. <param-value>/WEB-INF/log4j.properties</param-value>
    9. </context-param>
    10. <servlet>
    11. <servlet-name>log4jInitServlet</servlet-name>
    12. <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>
    13. <load-on-startup>1</load-on-startup>
    14. </servlet>
    15. <servlet>
    16. <servlet-name>springInitServlet</servlet-name>
    17. <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    18. <load-on-startup>2</load-on-startup>
    19. </servlet>
    20. …
    21. </web-app>

      启动Spring容器时,需要得到两个信息:Spring配置文件的地址和Log4J属性文件,这两上信息分别通过contextConfigLocationWeb和log4jConfigLocation容器参数指定,如果有多个Spring配置文件,则用逗号隔开,如:

    /WEB-INF/applicationContext_1.xml, /WEB-INF/applicationContext_1.xm2

      由于在启动ContextLoaderServlet之前,必须事先初始化Log4J的引擎,所以Log4jConfigServlet必须在ContextLoaderServlet之前启动,这通过<load-on-startup>来指定它们启动的先后顺序。

      乱码是开发Web应用程序一个比较老套又常见问题,由于不同Web应用服务器的默认编码是不一样的,为了方便Web应用在不同的Web应用服务器上移植,最好的做法是Web程序自身来处理编码转换的工作。经典的作法是在web.xml中配置一个编码转换过滤器,Spring就提供了一个编码过滤器类CharacterEncodingFilter,下面,我们为应用配置上这个过滤器:

    1. <web-app>
    2. …
    3. <filter>
    4. <filter-name>encodingFilter</filter-name>
    5. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    6. <init-param>
    7. <param-name>encoding</param-name>
    8. <param-value>GBK</param-value>
    9. </init-param>
    10. </filter>
    11. <filter-mapping>
    12. <filter-name>encodingFilter</filter-name>
    13. <url-pattern>/*</url-pattern>
    14. </filter-mapping>
    15. …
    16. </web-app>

      Spring的过滤器类是org.springframework.web.filter.CharacterEncodingFilter,通过encoding参数指定编码转换类型为GBK,<filter-mapping>的配置使该过滤器截获所有的请示。

      Struts的框架也需要在web.xml中配置,想必读者朋友对Struts的配置都很熟悉,故在此不再提及,请参见本文所提供的源码。

      总结

      本文通过一个文件上传下载的Web应用,讲解了如何构建基于SSH的Web应用,通过Struts和FormFile,Spring的LobHandler以及Spring为HibernateBlob处理所提供的用户类BlobByteArrayType ,实现上传和下载文件的功能仅需要廖廖数行的代码即告完成。读者只需对程序作稍许的调整,即可处理Clob字段:

      ·领域对象对应Clob字段的属性声明为String类型;

      ·映射文件对应Clob字段的属性声明为org.springframework.orm.hibernate3.support.ClobStringType类型。

      本文通过SSH对文件上传下载简捷完美的实现得以管中窥豹了解SSH强强联合构建Web应用的强大优势。在行文中,还穿插了一些分层的设计经验,配置技巧和Spring所提供的方便类,相信这些知识对您的开发都有所裨益  
    展开全文
  • Ubuntu下的sftpftp性能差很

    千次阅读 2010-06-10 14:38:05
    可是用winscp或者filezilla下东西的时候最快不过700k。前两天我给办公室的机器装上了一个vftpd,下文件的速度一下子彪到了2-3m的速度,我用的ftp client软件还是filezilla而已。   看来sftp的服务为了安全性...

    ftp人人都知道,用来传输文件挺方便的,我办公室的ip是固定的,家里有时候需要工作一下的时候可以用ftp来共享文件。

     

    办公室我的操作系统装的ubuntu,家里用的是windows,如果家里用的也是ubuntu的话,用rsync是最方便的。目前我是用的ftp来同步文件的。

     

    首先我只在ubuntu上装了个openssh, 因为ssh自带sftp,我就没有另外装ftp的服务。可是用winscp或者filezilla下东西的时候最快不过700多k。前两天我给办公室的机器装上了一个vftpd,下文件的速度一下子彪到了2-3m的速度,我用的ftp client软件还是filezilla而已。

     

    看来sftp的服务为了安全性而牺牲了性能,这个代价也真是太大了,难道加密传输文件要占用这么大的资源么?我有点不能理解。。。

     

    另外,windows下面都没有一个直接的ssh.exe可以用,只有一些putty这样比较大而全的terminal,要不然就得去大费周章的下个cygwin才能有个单纯的ssh。

    展开全文
  • 解决了上传和下载的之后,又遇到了衣蛾新的问题,所有的网路请求都要求必须是https的,百度了一卷,说的都很多,但是试过之后都没什么很好的用处,于是决心自己潜心来研究一下。 首先,都提到要用openssl工具生成,...
  • 很多应用发布了很久依然搜索不到,大家知道发布到 Google Play 之后有一个月的推荐时期,但是如果应用的需求量本身不是很大或者 ASO 做的太也不会被搜索到,关注我的应该都是个人开发者,大多数是没有预算花钱推广...
  • 最近发现自己基础很差,自以为学的不错的东西,其实缺乏练习复习,基础十分不扎实。恶补无从下手,只得从以前的具体例子出发,在例子中发现能力存在的问题,结合实例复习掌握遗忘的本来就不扎实没学透的知识:...
  • iOS 任务下载(支持离线)

    千次阅读 2017-03-30 13:13:12
    代码下载代码下载地址效果展示分析说到iOS中的下载,有很多方式可以实现,NSURLConnection(已经弃用)就不说了,AFNetworking也不说了。我使用的是NSURLSession,常用的有3个任务类,NSURLSessionDataTask、...
  • iframe实现无刷新上传下载

    千次阅读 2012-10-21 22:20:40
    最近我维护的网站在审核时加了个上传下载的功能,能上传多个文件(文件小、不超过3个、上传时可以多选、且要有上传进度),下载时有选择的下载。页面是用aspx做的,微软自带的只有单文件上传,于是乎想到flash。找...
  • android 很多牛叉布局github地址

    千次阅读 2014-11-24 19:19:02
     乐于分享并且有一些不错的开源项目的个人组织,包括JakeWharton、Chris Banes、Koushik Dutta等大牛 第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView、ActionBar、...
  • springboot上传下载文件(1)(项目文件资源放在同一个服务器上) springboot上传下载文件(2)---搭建独立的文件服务器 springboot上传下载文件(3)--java api 操作HDFS集群+集群配置 springboot上传下载文件...
  • C/C++笔试题(很多

    万次阅读 2014-05-27 08:23:04
    微软亚洲技术中心的面试题!...(2)并发性:不仅进程之间可以并发执行,同一个进程的个线程之间也可并发执行 (3)拥有资源:进程是拥有资源的独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.  (4)系
  • SSH实现上传下载

    千次阅读 2008-12-14 16:59:00
    文件的上传和下载在J2EE编程已经是一个非常古老的话题了,也许您马上就能掰着指头数出好几个著名的大件:如SmartUpload、Apache的 FileUpload。但如果您的项目是构建在Struts+Spring+Hibernate(以下称SSH)框架上...
  • speedtest 测试服务器上传下载速度

    千次阅读 2019-04-02 21:06:34
    下载speedtest.py wget https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py 赋予执行权限 ls -l speedtest.py chmod u+x speedtest.py mv speedtest.py /usr/local/bin/speedtest-cli...
  • FTP上传下载的断点续传实现

    千次阅读 2012-09-06 21:38:17
    FTP上传下载的断点续传实现 发表时间:2010-7-23 6:27:13  FTP上传下载的断点续传实现  张国梁 --- CSDN:zglcl008  一:开发背景  由于需要对个服务器发布大的数据包,所以自己在LINUX...
  • 前话: 最近比较闲,用过百度/google/360/金山的云盘,想自己开发程序使用云盘API来上传和下载文件,之前了解过百度云存储API,一直没有试验过,所以今天试了一下,空间好像是1TB,确实蛮大的,样例中循环上传文件进行...
  • curl用ftp方式断点续传下载上传文件

    万次阅读 2010-11-27 16:01:00
      当时在开发《中国联通OSS-GSMWCDMA网络优化支撑系统部省接口技术》 时,部省接口广东省级系统需要在前端机采集华为bdf参数文件,由于网络设备原因,再经过次与广东省联通局方沟通,他们也不愿意...
  • 在调试之前看这个数据手册一脸懵,特别是MQTT部分还是独立的,这个前接触到的上海合宙的模块多少有点出处。另外就是那个AT命令的传入参数也是一脸懵,后来发现BC26的模块好像把MQTT部分单独的做成了支持阿里云...
  • Struts+Spring+Hibernate实现上传下载

    千次阅读 2006-01-04 15:48:00
    下载本文源代码引言 文件的上传和下载在J2EE编程已经是一个非常古老的话题了,也许您马上就能掰着指头数出好几个著名的大件:如SmartUpload、Apache的FileUpload。但如果您的项目是构建在Struts+Spring+Hibernate...
  • 小巫并不是一种教导别人怎么去面试的心态来写这篇文章的,我只是想把自己的经历与大家分享,或许你能在其中发现一些小巫没发现的东西,我愿意大家一起讨论进步。   这篇面试宝典主要有两块内容 一、...
  • 学习linux嵌入式开发已经快一个月了,注册了博客记录自己的学习过程,由于身边没有老师请教,中间走了很多弯路。由于本人记性较,写下博文便于自己记录,同时也方便其他新手参考。  自己在调试代码的时候 都是用...
  • 毕竟作为一款工具类,有基本的请求和下载功能,就差上传了,有点说不过去。好了,天不早了,咱干点正事吧。 如果你只想了解怎么用HttpClient来上传文件,可以参考这篇文章:http://blog.csdn.net/fengyuzhengf
  • 引言众所周知,无论是在任何的程序语言...而很多App在使用过程中出现各种莫名其妙的问题,多是由于开发人员使用多线程不当造成的,因此掌握在多线程及异步任务的原理使用方法非常有必要。一Android UI主线程设计原则
  • jquery实现文件上传

    千次阅读 2013-03-18 10:12:07
    原文地址:...继续我的‘不少于一个激动人心的’的旅程关于用Jquery探索ASP.NET,今天的文章将会演示怎样用Jquery上传多个文件,Fyneworks.com 已经创建了一个 ‘jQuery Multip
  • 线程断点续传后台下载

    千次阅读 2012-10-25 09:34:28
    本菜鸟最近在做一个小项目,项目中用到了多线程断点续传的功能,因为是菜鸟嘛,所以在网络上找了很多教程,不过大多教程只给出了源码,注释跟说明实在太少,也许大牛们不需要太多的解释,可是就苦了小菜们了。...
  • BTeMule下载协议的比较分析

    千次阅读 2008-05-14 23:03:00
    转载:http://www.yuanma.org/data/2008/0420/article_3009.htmBT...很多资料来源于互联网,再次向原作者表示感谢。 在当前的下载领域BTeMule协议应用得是最广泛得,他们各自有自己强大得用户阵迎得支持。 eDonke

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,453
精华内容 12,181
关键字:

下载和上传差很多