Поврежденный файл при использовании Java для загрузки файла - PullRequest
1 голос
/ 31 декабря 2008

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

Вот код, который мы используем для сохранения файла:

URL targetUrl = new URL(urlForFile);
InputStream content = (InputStream)targetUrl.getContent();
BufferedInputStream buffered = new BufferedInputStream(content);
File savedFile = File.createTempFile("temp",".dat");

FileOutputStream fos = new FileOutputStream(savedFile);
int letter;
while((letter = buffered.read()) != -1)
    fos.write(letter);
fos.close();

Позже я пытаюсь получить доступ к этому файлу с помощью:

ObjectInputStream keyInStream = new ObjectInputStream(new FileInputStream(savedFile));

Большую часть времени это работает без проблем, но время от времени мы получаем ошибку:

java.io.StreamCorruptedException: invalid stream header: 0D0A0D0A

, что заставляет меня поверить, что файл не сохраняется правильно.

Ответы [ 5 ]

4 голосов
/ 31 декабря 2008

Я предполагаю, что операции, которые вы выполнили с помощью getContent и BufferedInputStream, обработали файл как файл ascii, который преобразовал переводы новой строки или возврата каретки в возврат каретки + перевод новой строки (0x0d0a), что привело к путанице в ObjectInputStream (который ожидает сериализацию объекты данных.

1 голос
/ 31 декабря 2008

В вашем примере кода есть 3 большие проблемы:

  1. Вы не просто обрабатываете ввод как байты
  2. Вы без необходимости вытягиваете весь объект в память сразу
  3. Вы делаете несколько вызовов методов для каждого прочитанного и записанного байта - используйте чтение / запись на основе массива!

Вот повтор:

URL targetUrl = new URL(urlForFile);
InputStream is = targetUrl.getInputStream();
File savedFile = File.createTempFile("temp",".dat");
FileOutputStream fos = new FileOutputStream(savedFile);

int count;
byte[] buff = new byte[16 * 1024];
while((count = is.read(buff)) != -1) {
    fos.write(buff, 0, count);
}
fos.close();
content.close();
1 голос
/ 31 декабря 2008

Почему вы используете ObjectInputStream для чтения?

Согласно документу Javadoc:

ObjectInputStream десериализует примитивные данные и объекты ранее записанные с использованием ObjectOutputStream.

Возможно, ошибка связана с тем, что вы не написали ее с помощью ObjectOutputStream.

Попробуйте прочитать его только с FileInputStream.

Вот образец для двоичного файла (хотя и не самый эффективный способ)

Вот другой , используемый для текстовых файлов.

1 голос
/ 31 декабря 2008

Если вы используете URL-адрес FTP, передача может происходить в режиме ASCII.

Попробуйте добавить "; type = I" в конец вашего URL.

0 голосов
/ 31 декабря 2008

Вы также можете отступить от кода и проверить, совпадает ли файл на вашем клиенте с файлом на сервере. Если вы получите оба файла на машине с XP, вы сможете использовать утилиту FC для сравнения (обратитесь к справке FC, если вам нужно запустить это как двоичное сравнение, так как для этого есть переключатель). Если вы работаете в Unix, я не знаю программу сравнения файлов, но я уверен, что что-то есть.

Если файлы идентичны, значит, вы видите проблему с кодом, который читает файл.

Если файлы не идентичны, обратите внимание на код, который записывает ваш файл.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...