日期:2014-05-20  浏览次数:20773 次

URLConnection上传文件越来越卡,最后内存溢出
由于单个文件较大,将文件进行分割,然后上传到服务端,服务端进行拼接,结果开始100M速度还行,后来越来越慢,最后就内存溢出了,眼拙没看错来哪里出了问题,求指点,代码如下:
客户端代码:
Java code


                        URL serverURL = new URL(url);
                        //支持多文件上传
                        for(int i=0;i<files.length;i++)
                        {
                            URLConnection conn = null;
                            //每次重新打开连接
                            try {
                                conn = serverURL.openConnection();
                            } catch (Exception e) {
                                e.printStackTrace();
                                throw new RuntimeException("无法连接到服务器");
                            }
                            //相同文件上传的头信息都相同
                            int cutIndex = 1;//拆分数量
                            conn.setRequestProperty("cc", "zc");
                            conn.setRequestProperty("dirXh", dirxh);
                            conn.setRequestProperty("wdxh", (String)ret.get(i));
                            conn.setRequestProperty("cutIndex", "1");
                            conn.setRequestProperty("opr", "" + Constant.DOC_UPLOAD);
                            conn.setDoInput(true);
                            conn.setDoOutput(true);
                            BufferedInputStream in = new BufferedInputStream(new FileInputStream(files[i]));
                            BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());

                            byte[] temp = new byte[1024];
                            byte[] _temp = null;
                            int length = -1;
                            /** 由于outputStream不是一个网络流,读取的数据没有立即传输到服务端,而是存储在内存中,
                             * 等读取完之后再写到服务端,所以单个文件过大会导致JVM内存溢出,
                             * 所以此处通过对文件进行分割,每次传输20M(20*1024*1024byte),将分割信息记录到头信息中
                             * 在服务端对信息再进行拼装 */
                            int count = 0;
                            while ((length = in.read(temp)) != -1){
                                if ((count + 1) % (20 * 1024) == 0) {//每20M
                                    out.flush();
                                    out.close();
                                    out = null;
                                    InputStream inputStream = conn.getInputStream();
                                    inputStream.close();
                                    inputStream = null;
                                    conn = null;
                                    try {
                                        conn = serverURL.openConnection();
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        throw new RuntimeException("无法连接到服务器");
                                    }
                                    //一次上传的头信息都相同
                                    conn.setRequestProperty("cc", "zc");
                                    conn.setRequestProperty("dirXh", dirxh);
                                    conn.setRequestProperty("wdxh", (String)ret.get(i));
                                    conn.setRequestProperty("cutIndex", "" + (++cutIndex));
                                    conn.setRequestProperty("opr", "" + Constant.DOC_UPLOAD);
                                    conn.setDoInput(true);
                                    conn.setDoOutput(true);
                                    out = new BufferedOutputStream(conn.getOutputStream());
                                }
                                if (length != temp.length) {
                                    _temp = new byte[length];
                                    System.arraycopy(temp, 0, _temp, 0, length);
                                    temp = _temp;
                                }
                                out.write(temp);
                                count ++;
                            }
                            out.flush();
                            out.close();
                            out = null;
                            in.close();
                            //为什么要读取服务端的返回信息时服务端才认定客户端的传输已经结束?
                            InputStream inputStream = conn.getInputStream();
                            inputStream.close();
                            inputStream = null;
                        }