У меня есть встроенное устройство, которое запускает Java-приложения, которые могут, помимо прочего, обслуживать веб-страницы XHTML (я мог бы написать страницы как что-то отличное от XHTML, но сейчас я стремлюсь к этому).
При получении запроса на веб-страницу, обрабатываемую моим приложением, в моем коде вызывается метод, содержащий всю информацию о запросе, включая поток вывода для отображения страницы.
На одной из моих страниц я хотел бынапример, для отображения (журнала) файла, размер которого может достигать 1 МБ.
Я могу отобразить этот файл без экранирования, используя следующий код:
<code>final PrintWriter writer; // Is initialized to a PrintWriter writing to the output stream.
final FileInputStream fis = new FileInputStream(file);
final InputStreamReader inputStreamReader = new InputStreamReader(fis);
try {
writer.println("<div id=\"log\" style=\"white-space: pre-wrap; word-wrap: break-word\">");
writer.println(" <pre>");
int length;
char[] buffer = new char[1024];
while ((length = inputStreamReader.read(buffer)) != -1) {
writer.write(buffer, 0, length);
}
writer.println("
"); writer.println (" ");} finally {if (inputStreamReader! = Null) {inputStreamReader.close ();}}
Это работает достаточно хорошо и отображает весь файл в течение одной или двух секунд (приемлемый период).
Этот файл может (и на практике содержит) символы, которые являются недопустимыми XHTML, чаще всего <>
. Поэтому мне нужно найти способ экранирования этих символов.
Первое, что я попробовал, был раздел CDATA, но, как задокументировано здесь , они не отображаются правильно в IE8.
Вторым, что я попробовал, был метод, подобный следующему:
// Based on code: /386117/luchshii-sposob-kodirovat-tekstovye-dannye-dlya-xml-v-java#386145
// Modified to write directly to the stream to avoid creating extra objects.
private static void writeXmlEscaped(PrintWriter writer, char[] buffer, int offset, int length) {
for (int i = offset; i < length; i++) {
char ch = buffer[i];
boolean controlCharacter = ch < 32;
boolean unicodeButNotAscii = ch > 126;
boolean characterWithSpecialMeaningInXML = ch == '<' || ch == '&' || ch == '>';
if (characterWithSpecialMeaningInXML || unicodeButNotAscii || controlCharacter) {
writer.write("&#" + (int) ch + ";");
} else {
writer.write(ch);
}
}
}
Это правильно экранирует символы (я собирался расширить его, чтобы экранировать недопустимые символы HTML, если это необходимо), новеб-страница затем занимает более 15 секунд для отображения, а другие ресурсы на странице (изображения, таблица стилей CSS) периодически не загружаются (я полагаю, из-за истечения времени ожидания запросов на них из-за привязки процессора).
IЯ пытался использовать BufferedWriter
перед PrintWriter
, а также изменять размер буфера (как для чтения файла, так и для BufferedWriter
) различными способами, без улучшения.
IsЕсть ли способ избежать всех недопустимых символов XHTML, который не требует повторения для каждого символа в потоке?В случае неудачи, есть ли способ ускорить мой код, достаточный для отображения этих файлов в течение пары секунд?
Я рассмотрю вопрос об уменьшении размера файлов журнала, если придется, но я надеялся сделать ихразмером не менее 250-500 КБ (при этом идеальным является 1 МБ).
У меня уже есть метод для простой загрузки файлов журнала, но я хотел бы отобразить их в браузере, а также для простого устранения неполадок / прочтения.
Если есть способ установить заголовки так, чтобы IE8 / Firefox просто отображал файл в браузере как текстовый файл, я бы посчитал это альтернативой (и имел бы целую страницу, посвященную файлу безXHTML любого типа).
РЕДАКТИРОВАТЬ:
После внесения изменения , предложенного Кэмероном Скиннером, и тестирования производительности это выглядит так, как будто на запись с выходом уходит около 1,5-В 2 раза длиннее, чем блочная версия.Это не что иное, но я, вероятно, не смогу добиться огромного ускорения, возиться с ним.
Возможно, мне просто нужно уменьшить максимальный размер файла журнала.