Java 将csv文件动态写入servlet响应输出流

Java 将csv文件动态写入servlet响应输出流,java,servlets,Java,Servlets,我有超过100万的数据库数据。我需要一次从DB1000行中读取数据,并将其写入OutputStream,直到没有返回数据为止。我不确定能收集多少数据。因此,在到达数据末尾之前,我不知道文件的长度 是否有可能将数据批量写入outputstream,而这些数据应该同时传输到网络。我在这里试图实现的是避免内存不足。如果我在输出流中保留100万个数据,它将停止运行。所以为了避免OOM,我试图将数据写入网络,它不应该保存在任何JVM内存中,它应该在我得到数据后立即写入网络。到目前为止,我编写的代码就在这里

我有超过100万的数据库数据。我需要一次从DB1000行中读取数据,并将其写入OutputStream,直到没有返回数据为止。我不确定能收集多少数据。因此,在到达数据末尾之前,我不知道文件的长度

是否有可能将数据批量写入outputstream,而这些数据应该同时传输到网络。我在这里试图实现的是避免内存不足。如果我在输出流中保留100万个数据,它将停止运行。所以为了避免OOM,我试图将数据写入网络,它不应该保存在任何JVM内存中,它应该在我得到数据后立即写入网络。到目前为止,我编写的代码就在这里

注意:这是独立代码

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    // TODO Auto-generated method stub
    String header = "Doc Timestamp,Internal DocID,DocType,Sender,Receiver,Routing Status,User Status,External DocID\n";
    resp.setHeader("Content-Disposition", "attachment; filename="+"File.csv"); 
    resp.setContentType("text/csv");

    OutputStream stream = resp.getOutputStream();
    stream.write(header.getBytes());
    stream.flush();

    for (int i = 0; i < 10000000; i++) {
        String docTimeStamp = new Date().toString();
        String docid = UUID.randomUUID().toString();
        String docType = "ICSCSRin";
        String sender = "ACC15796_CWS";
        String receiver = "ACC15794_CWS";
        String routingStatus = "DONE W/ ERRORS";
        String userStatus = "CWS POST_PROCESS";
        String snrf = "CWS_TES";
        StringBuffer str = new StringBuffer();
        str.append(docTimeStamp).append(",").append(docid).append(",").append(docType).append(",").append(sender).append(",").append(receiver).append(",").append(routingStatus).append(",").append(userStatus).append(",").append(snrf).append("\n");
        stream.write(str.toString().getBytes());
    }
    stream.close();
}
protectedvoid doGet(HttpServletRequest-req、HttpServletResponse-resp)
抛出ServletException、IOException{
//TODO自动生成的方法存根
String header=“文档时间戳、内部文档ID、文档类型、发件人、收件人、路由状态、用户状态、外部文档ID\n”;
相应的setHeader(“内容处置”、“附件;文件名=“+”File.csv”);
分别为setContentType(“文本/csv”);
OutputStream=resp.getOutputStream();
stream.write(header.getBytes());
stream.flush();
对于(int i=0;i<10000000;i++){
字符串docTimeStamp=new Date().toString();
字符串docid=UUID.randomUUID().toString();
字符串docType=“ICSCSRin”;
字符串发送者=“ACC15796_CWS”;
字符串接收器=“ACC15794_CWS”;
字符串routingStatus=“完成,但有错误”;
字符串userStatus=“CWS POST_过程”;
字符串snrf=“CWS_TES”;
StringBuffer str=新的StringBuffer();
str.append(docTimeStamp).append(“,”).append(docid).append(“,”).append(docType).append(“,”).append(发送方).append(“,”).append(接收方).append(路由状态).append(“,”).append(用户状态).append(“,”).append(“,”).append(snrf).append(“\n”);
stream.write(str.toString().getBytes());
}
stream.close();
}

是的,这是可能的。由于HTTP协议通常在发送响应之前提供响应的大小,因此在这种情况下,它将检测到它无法做到这一点,并对HTTP响应使用稍微修改的协议(分块编码),但它确实有效。不确定代码是独立的是什么意思。它不包含main()方法,因此它不是独立的。输出流不保存在内存中。您冲入其中的所有内容都应该由客户端读取,否则它会阻塞。但要不时刷新。@Real怀疑论者刷新应该在缓冲区满时隐式完成。@kumesana是的,但您不知道缓冲区的大小以及何时会发生。不发送内容长度头的http应用程序的真正问题是超时。“在已知点冲洗可能有助于避免这种情况。”Real怀疑论者从未遇到过这样的情况,即这是一个问题的正确解决方案,但我认为可能存在一些问题。