Мне очень трудно отладить проблему с приложением, которое я создавал. Сама проблема, которую я не могу воспроизвести с помощью программы репрезентативного тестирования с той же проблемой, которую трудно продемонстрировать. К сожалению, я не могу поделиться своим фактическим источником из-за безопасности, однако следующий тест довольно хорошо отражает то, что я делаю, тот факт, что файлы и данные имеют формат EOL в стиле Unix, запись в zip-файл с помощью PrintWriter и использование StringBuilders :
public class Tester {
public static void main(String[] args) {
// variables
File target = new File("TESTSAVE.zip");
PrintWriter printout1;
ZipOutputStream zipStream;
ZipEntry ent1;
StringBuilder testtext1 = new StringBuilder();
StringBuilder replacetext = new StringBuilder();
// ensure file replace
if (target.exists()) {
target.delete();
}
try {
// open the streams
zipStream = new ZipOutputStream(new FileOutputStream(target, true));
printout1 = new PrintWriter(zipStream);
ent1 = new ZipEntry("testfile.txt");
zipStream.putNextEntry(ent1);
// construct the data
for (int i = 0; i < 30; i++) {
testtext1.append("Testing 1 2 3 Many! \n");
}
replacetext.append("Testing 4 5 6 LOTS! \n");
replacetext.append("Testing 4 5 6 LOTS! \n");
// the replace operation
testtext1.replace(21, 42, replacetext.toString());
// write it
printout1 = new PrintWriter(zipStream);
printout1.println(testtext1);
// save it
printout1.flush();
zipStream.closeEntry();
printout1.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Суть проблемы в том, что файл, который я вижу на моей стороне, создает файл длиной 16,3 тыс. Символов. Мой друг, независимо от того, использует ли он приложение на своем компьютере или он просматривает тот же файл, что и я, видит файл с 19,999 тыс. Символов, дополнительные символы - CRLF, за которым следует огромное количество нулевых символов. Независимо от того, какое приложение, кодировку или представления я использую, я вообще не могу видеть эти нулевые символы, я вижу только один LF в последней строке, но я вижу файл размером 20 КБ. Во всех случаях существует разница между тем, что видно с одинаковыми файлами на двух компьютерах, даже если оба являются компьютерами Windows, и оба используют одни и те же программы для редактирования.
Я еще не смог воспроизвести это поведение с любым количеством фиктивных программ. Тем не менее, я смог проследить отклонение CRLF в последней строке до моего использования println на PrintWriter. Когда я заменил println(s)
на print(s + '\n')
, проблема, казалось, исчезла (размер файла 16,3 КБ). Однако, когда я вернул программу в println (s), проблема, похоже, не возвращается. В настоящее время я проверяю файлы, полученные от друга во Франции, чтобы выяснить, действительно ли проблема исчезла (поскольку я не вижу nuls, но он может), но это поведение было полностью запутано.
Я также заметил, что функция замены StringBuilder сообщает: «Эта последовательность будет удлинена, чтобы приспособить указанную строку при необходимости». Принимая во внимание тот факт, что функция setLength для строителей строк дополняется нулевыми символами и что функция sureCapacity устанавливает емкость на большее из входного значения или (currentCapacity*2)+2
, я подозревал где-то отношение. Тем не менее, я только один раз, когда тестировал с этой идеей, смог получить результат, который представлял то, что я видел, и не смог воспроизвести его с тех пор.
Кто-нибудь знает, что может быть причиной этой ошибки, или, по крайней мере, есть предложение о том, в каком направлении следует проводить тестирование?
Изменить, так как раздел комментариев для меня не работает:
Просто чтобы прояснить, вывод должен быть в формате Unix независимо от ОС, следовательно, использование '\ n' напрямую, а не через форматтер. Оригинальный StringBuilder, который вставлен в, на самом деле не сгенерирован для меня, а представляет собой содержимое файла, считываемого программой. Я рад, что процесс чтения работает, так как информация в нем интенсивно используется во всем приложении. Я также провел небольшое исследование и обнаружил, что непосредственно перед сохранением буфер является правильной емкостью, а вывод при вызове toString () имеет правильную длину (то есть он не содержит нулевых символов и имеет длину 16 363, а не 19 999). ). Это приведет к возникновению ошибки где-то между генерацией строки и сохранением zip-файла.