2015-09-03 4 views
1

У меня есть простой класс сервлета, который возвращает CSV-файл клиенту (браузеру). Когда я попытался написать строку в поток. Первоначально я следовал примеру A), однако я заметил, что подмножество ожидаемых данных добавляется.запись строки в выходной поток в java

Предположим, я ожидаю, что в CSV-файле будут записаны точные 100 записей. Каждая запись представляет собой «имя/фамилия/возраст». В примере A) я получил 120. Первые 100 записей правильные, но подмножество из 100 в этом случае добавлено 20 (дубликатов).

пример А)

public void returnCSV(HttpServletResponse resp, String data) { 
    ServletOutputStream out = resp.getOutputStream(); 
    InputStream in = new ByteArrayInputStream(data.getBytes("UTF-8")); 
    byte[] bytes = new byte[4096]; 
    while (in.read(bytes,0,4096) != -1) { 
     out.write(bytes,0,4096); 
    } 
    in.close(); 
    out.flush(); 
    out.close(); 
} 

После прочтения больше потоков относительно преобразования строки в поток. Я решил следовать примеру B), который произвел корректный вывод 100 записей. Но я не понимаю, почему первый пример А) добавил бы дубликаты данных.

пример B)

public void returnCSV(HttpServletResponse resp, String data) { 
    ServletOutputStream out = resp.getOutputStream(); 
    out.write(data.getBytes("UTF-8"));   
    out.flush(); 
    out.close(); 
} 

ответ

1

Посмотрите на эту петлю:

while (in.read(bytes,0,4096) != -1) { 
    out.write(bytes,0,4096); 
} 

Однако большой объем данных считывается read, вы всегда выписывая 4096 байт. Вы хотите только скопировать то же количество данных, которое вы прочитали, например.

int bytesRead; 
while ((bytesRead = in.read(bytes)) != -1) { 
    out.write(bytes, 0, bytesRead); 
} 

Есть много сторонних библиотек, которые имеют код для копирования из входного потока в выходной поток, заметьте - и вы должны использовать примерочных с-ресурсов заявления, чтобы закрыть потоки в любом случае.

Кроме того, вместо звонка getOutputStream, вы должны позвонить ServletResponse.getWriter, потенциально после звонка ServletResponse.setCharacterEncoding, чтобы убедиться, что он использует UTF-8. Затем вы можете позвонить:

writer.write(data); 

Писатели предназначены для ввода текстовых данных; выходные потоки предназначены для записи двоичных данных. Вы можете создать запись поверх потока с помощью OutputStreamWriter, но поскольку API сервлета сделает это за вас, вы также можете это сделать ...

+0

Благодарим вас за разъяснения и советы. – DaeYoung

+0

resp.setCharacterEncoding ("UTF-8"); . Resp.getWriter() записи (данные); отлично работает! Благодаря! – DaeYoung

Смежные вопросы