看提示好象是内存溢出,不应该是sql server的问题,因为一个image或text的理论值是2G-1个字节. OutOfMemoryError ,你把三四十M的内容放在memory里面很可能就溢出了.

解决方案 »

  1.   

    文件SaveFile.javapackage uploadfile;import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.*;
    import java.util.*;
    import java.sql.*;
    import java.text.*;/**
     * <p>Title: </p>
     * <p>Description: </p>
     * <p>Copyright: Copyright (c) 2003</p>
     * <p>Company: </p>
     * @author not attributable
     * @version 1.0
     */public class SaveFile extends HttpServlet
    {
      private static final String CONTENT_TYPE = "text/html; charset=GBK";
      private static final String INSERT = "insert into fileData (fileName,fileExt,fileData) values (?,?,?)";
      private static final String SELECT_INSERT_ID = "select @@identity as id";
      private static final String SELECT = "select * from fileData where id = ?";  boolean hasError = false;
      String fileName = "";                 //文件名
      String fileExt = "";                  //由页面传过来的文件路径和文件名
      byte[] fileData;                      //文件数据
      //Initialize global variables
      public void init() throws ServletException
      {
      }
      //Process the HTTP Get request
      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        this.save(request,response);
      }
      //Process the HTTP Post request
      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        this.save(request,response);
      }  public void save(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException
      {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();    ParsePutFileHttpStream hStream = new ParsePutFileHttpStream(request, response);    if(hStream.getParams("fileName")!=null) { this.fileName = (String) hStream.getParams("fileName"); }
        //得到文件数据
        this.fileData = hStream.getFileByte();
        //得到物理文件名
        if(hStream.getParams("filename")!=null) { this.fileExt = (String) hStream.getParams("filename"); }
        java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(fileExt, "\\");
        while (tokenizer.hasMoreTokens())
        {
          if (tokenizer.countTokens() == 1)
          {
            this.fileExt = tokenizer.nextToken();
          }
          else
          {
            tokenizer.nextToken();
          }
        }
    ///////////以下判断各数据合法性////////////////////////    //文件物理名或扩展名
        if ("".equals(this.fileExt) || this.fileExt == null)
        {
          this.hasError = true;
          out.println("<script language='javascript'>");
          out.println("alert('文件名不能为空')");
          out.println("window.history.back()");
          out.println("</script>");
        }
        //判断文件数据
        if (this.fileData == null)
        {
          this.hasError = true;
          out.println("<script language='javascript'>");
          out.println("alert('文件不能为空')");
          out.println("window.history.back()");
          out.println("</script>");
        }
        if (this.fileData.length == 0)
        {
          this.hasError = true;
          out.println("<script language='javascript'>");
          out.println("alert('文件长度不能为空')");
          out.println("window.history.back()");
          out.println("</script>");
        }    //文件名称
        if((this.fileName == null)||(this.fileName.equals("")))
        {
          this.hasError = true;
          out.println("<script language='javascript'>");
          out.println("alert('文件别名不能为空')");
          out.println("window.history.back()");
          out.println("</script>");
        }    //保存数据
        try
        {
          this.insertData();
          out.println("</body></html>");
          out.println("<script language='javascript'>");
          out.println("alert('文件上传成功')");
          out.println("window.history.back()");
          out.println("</script>");
        }
        catch (SQLException e)
        {
          out.println("<script language='javascript'>");
          out.println("alert('SQLException:"+e.getMessage()+"')");
          out.println("window.history.back()");
          out.println("</script>");
        }
        catch(Exception e1)
        {
          out.println("<script language='javascript'>");
          out.println("alert('Exception:"+e1.getMessage()+"')");
          out.println("alert('Exception:"+e1.toString()+"')");
          out.println("window.history.back()");
          out.println("</script>");
        }  }  private void insertData() throws SQLException,Exception
       {
         if(!this.hasError)
         {
           Connection con = DatabaseConnection.getConnection();
           byte[] tmp = new byte[4096];
           tmp[0] = this.fileData[0];
           //com.sybase.jdbcx.TextPointer tp = null;
           PreparedStatement pst = null;
           con.setAutoCommit(false);
           try
           {
             pst = con.prepareStatement(this.INSERT);
             pst.setString(1, this.fileName);
             pst.setString(2, this.fileExt);
             pst.setBytes(3, this.fileData);
             pst.execute();
             con.commit();
           }
           catch (SQLException e1)
           {
             con.rollback();
             throw new SQLException(e1.toString());
           }
           catch(Exception e)
           {
             con.rollback();
             throw new Exception(e.toString());
           }
           finally
           {
             try
             {
               if (pst != null)
               {
                 pst.close();
                 pst = null;
               }
             }
             catch (SQLException e)
             {}
           }
         }
       }  //Clean up resources
      public void destroy()
      {
      }
    }
      

  2.   

    文件ParsePutFileHttpStream.javapackage uploadfile;import javax.servlet.http.*;
    import javax.servlet.*;
    import javax.naming.*;
    import java.util.*;
    import java.io.*;
    /**
     * <p>Title: </p>
     * <p>Description: </p>
     * <p>Copyright: Copyright (c) 2002</p>
     * <p>Company: </p>
     * @author not attributable
     * @version 1.0
     */public class ParsePutFileHttpStream
    {  private static final char CR = 13;
      private static final char LF = 10;  protected String boundary = null;
      protected Hashtable params = new Hashtable();
      private byte[] fileByte;  public ParsePutFileHttpStream(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      {
        ServletInputStream in = request.getInputStream();
        BufferedInputStream bin = new BufferedInputStream(in);
        boundary = getBoundary(request.getHeader("content-type"));    PrintWriter out = response.getWriter();
        //out.println("<html><body><pre>");
        //out.println("boundary=\n" + boundary);
        //out.println();    byte[] bytes = new byte[4096];
        in.readLine(bytes, 0, bytes.length);
        String line = new String(bytes);
        Hashtable header = null;
        while (in.readLine(bytes, 0, bytes.length) >= 0)
        {
          line = new String(bytes);
          if (line.startsWith("Content-Disposition:"))
          {
            //out.println(line);
            System.out.println(line);
            header = parseHeader(line);
            updateParams(header);
          }
          else if (line.startsWith("Content-Type:"))
          {
            params.put("Content-Type", line.substring("Content-Type:".length()).trim());
          }
          else
          {
            if (header != null && bytes[0] == 13)
            {
              if (header.containsKey("filename"))
              {
                displayParams(out);
                //out.println("  ...saving payload");
                System.out.println("  ...saving payload");
                paserFileStream(bin);
                header = null;
              }
              else
              {
                String name = (String) header.get("name");
                String value = getParameter(in).trim();
                params.put(name, value);
              }
            }
            if (line.indexOf(boundary) >= 0)
            {
              //out.println(line);
            }
            if (line.indexOf(boundary) >= 0)
            {
              System.out.println(line);
            }
          }
          bytes = new byte[4096];
        }
        //out.println(this.fileByte.length);
      }  private void paserFileStream(BufferedInputStream is) throws IOException
      {
        int c;
        PushbackInputStream input = new PushbackInputStream(is, 4096);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        while ( (c = read(input, boundary)) >= 0)
        {
          out.write(c);
        }
        fileByte = out.toByteArray();
        out.close();
        input.close();
      }  private String getParameter(ServletInputStream in) throws java.io.IOException
      {
        byte[] bytes = new byte[4096];
        in.readLine(bytes, 0, bytes.length);
        return new String(bytes);
      }  private String getBoundary(String contentType)
      {
        int bStart = contentType.indexOf("boundary=") + "boundary=".length();
        return "" + CR + LF + "--" + contentType.substring(bStart);
      }  private int read(PushbackInputStream input, String boundary) throws IOException
      {
        StringBuffer buffer = new StringBuffer();
        int index = -1;
        int c;    do
        {
          c = input.read();
          buffer.append( (char) c);
          index++;
        }
        while ( (buffer.length() < boundary.length()) && (c == boundary.charAt(index))); if (c == boundary.charAt(index))
        {
          int type = -1;
          if (input.read() == '-')
          {
            type = -2;
          }
          while (input.read() != LF)
          {
            ;
          }
          return type;
        }
        while (index >= 0)
        {
          input.unread(buffer.charAt(index));
          index--;
        }
        return input.read();
      }  private Hashtable parseHeader(String line)
      {
        Hashtable header = new Hashtable();
        String token = null;
        StringTokenizer st = new StringTokenizer(line, ";");
        while (st.hasMoreTokens())
        {
          token = st.nextToken().trim();
          String key = "";
          String val = "";
          int eq = token.indexOf("=");
          if (eq < 0)
          {
            eq = token.indexOf(":");
          }
          if (eq > 0)
          {
            key = token.substring(0, eq).trim();
            val = token.substring(eq + 1);
            val = val.replace('"', ' ');
            val = val.trim();
            header.put(key, val);
          }
        }
        return header;
      }  private void updateParams(Hashtable header)
      {
        for (Enumeration e = header.keys(); e.hasMoreElements(); )
        {
          String key = (String) e.nextElement();
          params.put(key, header.get(key));
        }
      }  private void displayParams(PrintWriter out)
      {
        for (Enumeration e = params.keys(); e.hasMoreElements(); )
        {
          String key = (String) e.nextElement();
          System.out.println("  " + key + " = " + params.get(key));
        }
      }  public byte[] getFileByte()
      {
        return this.fileByte;
      }  public Object getParams(String param)
      {
        return params.get(param);
      }  protected void finalize()
      {
        params.clear();
        params = null;
      }}
      

  3.   

    pst.setBytes(3, this.fileData);
           ~~~~
    好像用这个就会出错,不能传大的文件,
    看有些资料上说应该用ByteArrayInputStream 不过我的ByteArrayInputStream 试验不成功,期待…………
      

  4.   

    哦,用的是 pstmt.setBinaryStream();
      

  5.   

    加油,使劲放,反正数据库倒了是以后的事情~BTW:每次看到有人往DB里面放大文件我就晕,不知道他们在想什么……
      

  6.   

    楼上:
    其实也不能一概而论,有的时候,需要保存一个图片,该怎么处理?就把文件放在服务器的硬盘上?(不过我们都是限制图片的大小,超过一定限度10M就拒绝上传了)楼主:
    pst.setBytes(3, this.fileData);
    应该是有问题的,
    一般大数据都采用流操作:先打开一个binaryStream,然后往里面写。
      

  7.   

    asdmonster(努力学习VC,讨回失去的信誉分)那我该怎么做?
    你能给我代码吗?因为我要传的主要是视频文件,所以很大
      

  8.   

    我试了,用setBinaryStream()也不行,说java.lang.OutOfMemoryError,按说用流的话文件大小应该不是问题,特郁闷~
    我这个文件是134M,小一些的文件没问题~
      public static void main(String[] args)
      {
             try
    {
      Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
      Connection conn = DriverManager.getConnection(
      "jdbc:microsoft:sqlserver://www:1433;DataBaseName=test",
      "sa", "");
      File file = new File("H:\\program\\photoshop6cn.zip");
      int length = (int) file.length();
      InputStream input = new FileInputStream(file);
      java.sql.PreparedStatement preStmt = conn.prepareStatement(
      "INSERT INTO [file] ([name],data) VALUES(?,?)");
      preStmt.setString(1, "fileName");
      preStmt.setBinaryStream(2, input, length);
      preStmt.execute();
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
      }
    我想楼主是视频文件就不要住数据库中放了,毕竟你还在播放~
      

  9.   

    告诉你的导师,数据量小可以,只要数据量大了一定完蛋!而且告诉他,别说SQL Server了,就是Oracle也一样完蛋。
      

  10.   

    告诉你的导师,数据量小可以,只要数据量大了一定完蛋!而且告诉他,别说SQL Server了,就是Oracle也一样完蛋。经典~
      

  11.   

    BTW:你的错误是Java内存不够,还不是垃圾SQL Server的问题。
      

  12.   

    那就是垃圾JAVA的问题啦~
    JAVA可否指定运行时占用内存大小?
      

  13.   

    accp(accp) 
    我要从表单提交文件,如果用你给的代码我怎么通过表单提交获得文件路径?
      

  14.   

    垃圾Java也是可以指定运行时需要的内存的!上传有没有进度请咨询M$公司,询问为什么上传没有进度。
    还有就是我个人认为数据库真正可以支持的文件大小是10k以下。最后就是为什么我指说Oracle和SQL Server,因为DB2,Informix等数据库厂商(……现在已经都是IBM了……)对于存储“内容”有其他的产品,只有Oracle和垃圾M$的垃圾SQL Server会硬上(告诉大家Oracle一个3000万的项目就是这么做砸的,数据库里面才有1500万记录,而且这是真正的大文件还不是在数据库,数据库里面还只是比较小的文件的时候就已经这样了,美国飞过来的专家一批又一批,最后也没有解决,让客户不得不1期用了不到半年就直接开始2期的。)
      

  15.   

    anni999(玉铃儿) :几十M是怎么传的啊,我的只能传10K,而且word文档上传到数据库倒出的时候还有问题.
      

  16.   

    呵,这垃圾JAVA够性的了,我用java -Xms32m -Xmx300m
    结果运行了十分钟也没把这个大文件存进去~
    我是不等了,谁有时间运行一下看~ps:跟大哥多学了一招,免得到时候做3000万的项目出问题~
    另外 xiaoyao888
    你在先上传,保存到服务器上,然后再往数据库中存~
      

  17.   

    刚才用另外一家公司的产品,看到他们的产品可以上传大文件,没有任何问题,不过看他们的jsp和源代码好像用的也是jspsmartupload,不过改动蛮大.
      

  18.   

    呵呵,最后一句:我用Java传过1.4G的文件
      

  19.   

    今天我告诉导师,数据量小可以,只要数据量大了一定完蛋!而且我还说,别说SQL Server了,就是Oracle也一样完蛋。导师沉默半天说100兆该可以吧崩溃!!我导师是VC高手,可是在JAVA方面他比我好不到哪去。因为本来他是让我用VC的,而我不想用VC,毕竟是做网页,用VC总不是很好呀,现在我用JSP,他也不得不去学JSP了,我把accp(accp) 给的代码改动了一下并采取他的建议(先上传,保存到服务器上,然后再往数据库中存)给导师演示,上传了118兆的文件,成功!花了5分钟,真是太慢了,有一段时间IE的进度条动都不动, 我还以为死机了呢。
    又传206兆的文件,等了10分钟,终于出错了,不过不是java.lang.OutOfMemoryError,而是SQL SERVER日志数据已满,这下是垃圾SQL Server的问题了吧,我看了一下SQL Server所在的文件夹,居然达到了1.65G,而我的D盘SQL Server的所在盘,只剩下7兆空间了,我关了SQL Server再开,又恢复到了600兆,我可不想再试了,我也没有时间等下去!
    现在把代码贴出来供和我一样有需要的人学习
    同时为了感谢大家积极回复我,我特意再加80分。up.html<html>
    <head>
    <title>上传文件</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>
    <body>
    <center>
    <font size=5 color=blue>上传文件</font>
    </center>
    <hr>
    <form action="upload.jsp" method="post" enctype="multipart/form-data">
    <p> 文件别名
    <input name="fileName" type="text" id="fileName">
    </p>
    <p> 选择文件
    <input type="FILE" name="FILE1" id="file">
    </p>
    <p>实验序号
    <input name="xuhao" type="text">
    </P>
    <p>实验名称
    <input name="nam" type="text">
    </P>
    <P>文件说明
    <textarea name="ind" rows="4" value=""></textarea>
    </P>
    <P>
    <input type="button" name="Submit" onclick="check()" value="提交">
    </p>
    </form>
    </body>
    </html>
    upload.jsp<%@ page contentType="text/html;charset=gb2312"%>
    <%@ page language="java" import="java.sql.*" %>
    <%@ page import="java.io.*"%>
    <jsp:useBean id="myUpload" scope="page" class="com.jspsmart.upload.SmartUpload" />
    <%
    String fnm=null;
    String[] values=null;
    String[] x=new String[4];
    int a=0;
    myUpload.initialize(pageContext);
    myUpload.upload();
    for (int i=0;i<myUpload.getFiles().getCount();i++)
    {
    com.jspsmart.upload.File myFile = myUpload.getFiles().getFile(i);
    if (!myFile.isMissing())
    {
    myFile.saveAs("/upload/" + myFile.getFileName());
        fnm=myFile.getFileName();
    }
    } java.util.Enumeration e = myUpload.getRequest().getParameterNames();
        while(e.hasMoreElements())
    {
    String key = (String)e.nextElement();
    values = myUpload.getRequest().getParameterValues(key);
    x[a]=values[0];
    a++;
    }
    %>
    <%
        String user=(String)session.getAttribute("usernm");
    String fn="C:\\Inetpub\\wwwroot\\up\\"+fnm;
    int xuhao=Integer.parseInt(x[0]);
    String ind=request.getParameter("ind");
    java.sql.Connection conn; 
    java.sql.Statement stmt; 
    java.sql.ResultSet rs1;  
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    conn=DriverManager.getConnection("jdbc:odbc:zxh");
    stmt=conn.createStatement();
    %>
    <%
    File file = new File(fn);
    int length = (int) file.length();
    InputStream input = new FileInputStream(file);

    PreparedStatement ps = conn.prepareStatement("insert into oka(实验序号,实验名称,上传者,别名,文件名,说明,image)values (?,?,?,?,?,?,?)");
    ps.setInt(1,xuhao);
    ps.setString(2,x[2]);
    ps.setString(3,user);
    ps.setString(4,x[3]);
    ps.setString(5,file.getName());
    ps.setString(6,x[1]);
    ps.setBinaryStream(7, input, length);
    ps.execute();

    ps.close();
    stmt.close();
    conn.close();


    out.println("<script language='javascript'>");
    out.println("alert('文件上传成功')");
    out.println("window.history.back()");
    out.println("</script>");
    %>
    上传文件到服务器,我用的是jspsmartupload组件
    不过这样速度真的很慢,等于花了双倍时间,如果有人有直接传数据库的代码,请发到
      

  20.   

    最后的回复:数据库能够支持的文件应该在10k以下,另外用了lob死的话不是因为100M的文件,而是因为记录数。补充:
    使用HTTP的Post方法的时候,文件会变大,因此HTTP本身就不适合大型文件传输的。