上传的代码如下,但是上传大文件时(比如60-70兆以上时),sql占用的内存大小会上浮到1.2G以上,不知道哪里有问题?因为问题出在sql上,所以和http与.net框架应该没有太大的关系,不知道是社么原因?谢谢各位兄弟上两次的贴子会一起结算,所以请各位能在下面的贴子里也贴一次,方便结算
http://community.csdn.net/Expert/topic/3871/3871482.xml?temp=.4059717
http://community.csdn.net/Expert/topic/3846/3846307.xml?temp=.5148126
Dim con As System.Data.SqlClient.SqlConnection
        Dim strcmd As String
        Dim cmd As System.Data.SqlClient.SqlCommand
        Dim intfilelen As Integer
        Dim objstream As System.IO.Stream
        con = New System.Data.SqlClient.SqlConnection(ConfigurationSettings.AppSettings("jxp"))        intfilelen = txtfilecontents.PostedFile.ContentLength
        Dim arrfile(intfilelen) As Byte
        objstream = txtfilecontents.PostedFile.InputStream
        objstream.Read(arrfile, 0, intfilelen)
        strcmd = "insert uploads (u_title,u_document) values (@u_title,@u_document)"
        cmd = New System.Data.SqlClient.SqlCommand(strcmd, con)
        cmd.Parameters.Add("@u_title", System.Data.SqlDbType.VarChar).Value = TextBox1.Text
        cmd.Parameters.Add("@u_document", System.Data.SqlDbType.Image).Value = arrfile        con.Open()
        cmd.ExecuteNonQuery()
        con.Close()

解决方案 »

  1.   

    http://community.csdn.net/Expert/topic/2733/2733618.xml
      

  2.   

    限制已经解除了,否则根本没有办法上传,现在问题是上传大文件时(60-70M)sql占用的内存已经达到1.2G,可怕啊
      

  3.   

    真的建议你别把文件放到SQL里面,这样对你的访问等性能并没有一点好处的,放到外面,然后里面用个字段保存文件名啊。这样不多好啊。!也便于管理不是吗
      

  4.   

    我做这个程序是为了保存公司里所有员工收进来的邮件的附件(做一个邮件网关,代替部分exchange的邮件网关功能),如果把附件保存到文件夹,会造成文件名的重复,可能替代掉别人的附件,因为这个不像其他的传图片应用,比较关键,重要附件丢失会有麻烦。
      

  5.   

    用数据库存储大的文件一定要分块存取!这个问题我所知道的从很早的VB开始就已经解决了,ado和ado.net里更是有专用的函数,看看msdn或搜一下以前的帖子吧!
    我在C#里把文件通过10M网卡存到sql server里的速度跟拷贝同一个文件的速度相差无几,额外占用的内存只跟每次的Block大小有关(例如8K)
      

  6.   

    Jacode(thinking...) ,你说的方法比较麻烦,收进来的文件要存到服务器指定的目录,别人的附件肯定会和以前的附件文件重复,以前的文件就会被覆盖,如果照你的看法,附件刚进来,就要改名字,哪迮么改呢?按照时间改?也会有重复的(比如同时几个人收邮件),我这里不像争论用社么方法保存附件,而只是想知道我的代码有哪些不合理的地方。谢谢
      

  7.   

    1.文件放在硬盘里面,改名字不会导致重名的。
    比如说用时间命名
    newfilename = DateTime.Now().toString("yyyyMMddhhmmss") + DateTime.Now.Millisecond.ToString()
    这样的的命名方式,以年月日时分秒再加毫秒,根本不可能重复,除非你的站点每秒钟同时都有数百人操作,但这根本不可能。
    2.你上面的写法有问题。这个的方式是一口气把文件写到数据库中,但我记得
    cmd.Parameters.Add("@u_document", System.Data.SqlDbType.Image).Value = arrfile
    里面还有个参数,对了,是偏移量,意思就是说碰到大文件时,要分多少次把它写进去。你试一下。
      

  8.   

    hchxxzx(net学习中) 
    能详细说一下那个偏移量的用法吗?我在书里好像没有看见过这个用法和这个词,谢谢。
      

  9.   

    Sql Server:http://support.microsoft.com/default.aspx?scid=kb;EN-US;309158Oracle:http://www.chinamacro.com/blog/visit_detail.aspx?blogID=53
      

  10.   

    对于你这种往数据库存储的问题,差不多应该是这样的:这种现象是正常的,当你查询数据的数据量比较大时,sqlserver会把查询结果缓存在内存中,保证你下次查询同样的记录时会很快得到结果,所以内存使用量会激增。
        在你完成此次查询后,sqlserver不会马上释放内存,数据会仍然放在内存中,这是sqlserver的优化策略,sqlserver会不断地占用你的系统内存,来加快sqlserver的运行速度,当你的系统中的其它服务也需要内存时,它才会自动释放部分内存。一句话,sqlserver不会让你的系统有闲置的内存,除非你设置sqlserver的最大内存使用量。这样也没什么不好,如果你的系统很大,单独给sqlserver一台机器,这样会提高它的性能。
        如果你只是开发用,要想让sqlserver释放内存,重启sqlserver的服务就行了。如果不想让sqlserver占用太多内存,设置sqlserver的最大内存占用量.
      

  11.   

    请参见如下程序,是我刚才在我笔记本上写出来测试的。很成功,在笔记本上做服务器,内存占用上升不大(笔记本做服务器,数据库在别的机止,在笔记本的IE里面进行上传)
    不过,数据库有点不同,是ORACLE9ISystem.Web.HttpPostedFile myFile = this.Request.Files[this.File1.ID];
    int myLength = myFile.ContentLength;if(myLength != 0)
    {
    System.IO.Stream myStream = myFile.InputStream; 
    byte[] myByte = new byte[myLength];
    myStream.Read(myByte,0,myLength); string sql = "insert into tst_myblob(id,blob) values(:id,:blob)";
    System.Data.OracleClient.OracleConnection conn = new OracleConnection("Data Source=xxx;user id=xxx;password=xxx");
    conn.Open(); System.Data.OracleClient.OracleCommand cmd = conn.CreateCommand();
    cmd.CommandText = sql;
    cmd.Parameters.Add(new OracleParameter("id",OracleType.Number));
    cmd.Parameters["id"].Value = this.TextBox1.Text;
    cmd.Parameters.Add(new OracleParameter("blob",OracleType.Blob));
    cmd.Parameters["blob"].Size = myLength;
    cmd.Parameters["blob"].Value = myByte;
    cmd.Parameters["blob"].Offset = 10;
    cmd.ExecuteNonQuery();
    }
      

  12.   

    我试过很多方法,SQL不要用来装这么大的东西,在本地机上都吃力,在网络中就更不用谈了!200M的加上去不死也残。。最好在SQL里面只装文件名和路径!!直接丢硬盘!!如果有高手解决此问题请指点!!还有就是SQL在连接数100-150的时候就残疾了响应时间上10秒(正版SQL)有什么好办法吗?
      

  13.   

    呵呵,
    1.文件放在硬盘里面,改名字不会导致重名的。
    比如说用时间命名
    newfilename = DateTime.Now().toString("yyyyMMddhhmmss") + DateTime.Now.Millisecond.ToString()
    这样的的命名方式,以年月日时分秒再加毫秒,根本不可能重复,除非你的站点每秒钟同时都有数百人操作,但这根本不可能。如果你还觉得有问题,完全可以后边加上5位的随机数,那样应该不会重复了吧?
    完全没有必要往数据库里写!那样最终回使你的SQL垮掉!
      

  14.   

    有谁知道hchxxzx(net学习中)说的偏移量的用法吗?我在书里好像没有看见过这个用法和这个词,谢谢。
      

  15.   

    偏移量??
    cmd.Parameters["blob"].Offset 
    上面的Offset就是偏移量。但没有详细测试过。-------------------------------------------
    Offset 属性用于客户端二进制和字符串数据分块。例如,为了将 10MB 的文本插入到服务器上的某一列中,用户可能会执行 10 次 1MB 块的参数化插入,在每次迭代中以 1MB 的大小移动 Offset 的值。该属性用于二进制和字符串类型。它返回二进制类型的字节数和字符串的字符数。字符串的计数不包括终止字符。