Чтение файла с использованием фиксированного числа байтов Java

1

Я пишу программу для копирования больших файлов, поэтому я хочу прочитать определенное количество байтов и записать в другой файл. Я хочу скопировать файл и получить такое же количество байтов. Но я получаю больше. Кроме того, я также хочу, чтобы содержимое файла оставалось таким же. Что я здесь делаю неправильно? Если кто-то может объяснить, почему я получаю этот дополнительный текст, это было бы здорово.

test.txt

sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext

Practice.java

public class Practice{
    public static void main(String[] args){

    byte[] buffer = new byte[100];

    try{
        FileInputStream f = new FileInputStream("test.txt");
        FileWriter writer = new FileWriter("copy_test.txt");
        int b;
        while ((b=f.read(buffer)) != -1 )
            writer.write(new String(buffer));
        writer.close();
    } catch(Exception e){
        e.printStackTrace();
    }
 }
}

copy_test.txt

sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
metext sometext sometext
sometext sometext sometext
  • 0
    А почему бы вам просто не использовать Files.copy() ?
  • 0
    Кроме того, вы используете InputStream в качестве источника и Writer качестве места назначения? А? В основном вы читаете яблоки, но пишете апельсины.
Показать ещё 2 комментария
Теги:
file
byte
filestream

1 ответ

5
Лучший ответ

Есть несколько проблем с вашим кодом:

  • Вы используете кодировку платформы по умолчанию для преобразования двоичных данных в текст (путем вызова new String(byte[]) вместо указания кодировки
  • Вы используете кодировку платформы по умолчанию для записи текста на диск (с помощью FileWriter)
  • Вы безоговорочно конвертируете весь свой буфер в текст, даже если ваше чтение не заполнило его - вы можете исправить это, используя одну из перегрузок конструктора String принимая смещение и количество байтов, и передавая 0 и b для аргументов, хотя я бы этого не сделал. Используйте инструкцию try-with-resources.
  • Вы не закрываете входной поток вообще, и если вы выбрали исключение, вы не закрываете запись. Используйте инструкцию try-with-resources.
  • Вы ловите Exception - это обычно плохая идея. Если вам необходимо, поймайте определенные исключения; лично у меня очень мало блоков catch - обычно, если что-то пойдет не так, для этого необходимо прекратить всю текущую операцию. (Конечно, есть случаи, когда вы можете повторить и т.д.) Я понимаю, что это может быть просто в вашем примере кода здесь, а не в вашем реальном коде.
  • Если вы просто пытаетесь скопировать файл, нет причин для преобразования между двоичным и текстовым вообще - придерживаться входных потоков и выходных потоков
  • Если вы просто пытаетесь скопировать файл, вы можете использовать Files.copy чтобы избежать необходимости писать какой-либо код вообще, предполагая, что вы используете Java 7. (И если вы этого не сделаете, вы должны быть!)

Если вы просто хотите скопировать InputStream в OutputStream (и у вас нет доступной библиотеки утилиты - это часть множества библиотек), вы можете просто использовать что-то вроде:

byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
    output.write(buffer, 0, bytesRead);
}
  • 0
    почему буфер размером 1024?
  • 0
    @ user3834119: почему бы и нет? Это похоже на разумный баланс между использованием памяти и чрезмерным вводом-выводом, хотя в потоке тоже может быть буферизация. Это несколько произвольное число - как и ваши 100, конечно.
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню