Tôi đang sử dụng Máy chủ ứng dụng Websphere của IBM v6 và Java 1.4 và đang cố ghi các tệp CSV lớn vào ServletOutputStream
để người dùng tải xuống. Các tệp khác nhau từ 50-750MB vào lúc này.Sử dụng ServletOutputStream để viết các tệp rất lớn trong một servlet Java không có vấn đề về bộ nhớ
Các tệp nhỏ hơn không gây ra quá nhiều vấn đề nhưng với các tệp lớn hơn, có vẻ như tệp đang được ghi vào heap, sau đó gây ra lỗi OutOfMemory và đưa toàn bộ máy chủ xuống.
Những tệp này chỉ có thể được phân phát cho người dùng được xác thực qua HTTPS, đó là lý do tại sao tôi phục vụ chúng thông qua Servlet thay vì chỉ gắn chúng vào Apache.
Mã Tôi đang sử dụng là (một số khuẩn loại bỏ khoảng này):
resp.setHeader("Content-length", "" + fileLength);
resp.setContentType("application/vnd.ms-excel");
resp.setHeader("Content-Disposition","attachment; filename=\"export.csv\"");
FileInputStream inputStream = null;
try
{
inputStream = new FileInputStream(path);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do
{
bytesRead = inputStream.read(buffer, offset, buffer.length);
resp.getOutputStream().write(buffer, 0, bytesRead);
}
while (bytesRead == buffer.length);
resp.getOutputStream().flush();
}
finally
{
if(inputStream != null)
inputStream.close();
}
Các FileInputStream
dường như không thể gây ra một vấn đề là nếu tôi viết vào tập tin khác hoặc chỉ loại bỏ các ghi hoàn toàn việc sử dụng bộ nhớ dường như không phải là vấn đề.
Điều tôi đang nghĩ là resp.getOutputStream().write
đang được lưu trữ trong bộ nhớ cho đến khi dữ liệu có thể được gửi qua máy khách. Vì vậy, toàn bộ tập tin có thể được đọc và lưu trữ trong các resp.getOutputStream()
gây ra vấn đề bộ nhớ của tôi và đâm!
Tôi đã thử Buffering các luồng này và cũng đã thử sử dụng Kênh từ java.nio
, không cách nào trong số đó dường như tạo ra bất kỳ sự khác biệt nào về vấn đề bộ nhớ của tôi. Tôi cũng đã xóa sạch OutputStream
một lần cho mỗi lần lặp của vòng lặp và sau vòng lặp, điều này không giúp ích gì.
Cố gắng thiết lập thuộc tính tùy chỉnh chứa Web Websphere này - com.ibm.ws.webcontainer.channelwritetype = sync chi tiết đang ở đây - http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/ index.jsp? topic =/com.ibm.websphere.express.doc/info/exp/ae/rweb_custom_props.html –