BufferOutputStream записва нулев байт при обединяване на файла

Опитвам се да обединя n части от файл в един файл. Но имам странно поведение на моята функция. Функцията се извиква x пъти за n секунди. Да кажем, че имам 100 файла, които ще обединя, всяка секунда извиквам 5 файла и ги обединявам. и в следващата секунда сумата се удвоява до 10, но от 1-5 е същият файл като преди, останалото е нов файл. Работи нормално, но в даден момент дава нулев байт или понякога дава правилния размер.

Бихте ли ми помогнали да открия грешката в моята функция по-долу?

public void mergeFile(list<String> fileList, int x) {
    int count = 0;
    BufferedOutputStream out = null;
    try {
        out = new BufferedOutputStream(new FileOutputStream("Test.doc"));
        for (String file : fileList) {
            InputStream in = new BufferedInputStream(new FileInputStream(file));
            byte[] buff = new byte[1024];
            in.read(buff);
            out.write(buff);
            in.close();
            count++;
            if (count == x) {
                break;
            }
        }
        out.flush();
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

*съжалявам за моя английски


person david    schedule 13.07.2012    source източник
comment
Това mergeFile се извиква ли от нишка?   -  person kv-prajapati    schedule 13.07.2012
comment
Ако се опитате да обедините MS Word doc файлове: Не мисля, че това работи, тъй като форматът не го позволява.   -  person eckes    schedule 09.10.2014


Отговори (2)


in.read(buff);

Проверете Javadoc. Не е гарантирано, че този метод ще запълни буфера. Той връща стойност, която ви казва колко байта е прочел. Трябва да използвате това и в тази ситуация трябва да го използвате, когато решавате колко байта, ако има такива, да запишете.

person user207421    schedule 13.07.2012
comment
съжалявам, че не те разбирам. Бихте ли обяснили малко повече? Благодаря - person david; 16.07.2012
comment
@david добавих връзка, ако я прочетете, обърнете внимание на върнатата стойност. може да бъде всичко между 0 и 1024 (или -1). И трябва да циклите, докато стане -1. - person eckes; 09.10.2014

Не четете целия файл, четете от всеки файл само до 1024 байта. Трябва да зациклите четенето, докато връща данни (или да използвате нещо като Files.copy().

BTW: нямате нужда от BufferedOutputStream, ако копирате с големи буфери.

public void mergeFile(list<String> fileList, int x) throws IOException {
    try (OutputStream out = new FileOutputStream("Test.doc");) {
        int count=0;
        for (String file : fileList) {
            Files.copy(new File(file).toPath(), out);
            count++;
            if (count == x) {
                break;
            }
        }
    }
}

Освен това не е необходимо да flush(), ако затворите. Тук използвам "опитай-с-ресурс", така че не е необходимо да го затварям изрично. Най-добре е да разпространявате изключенията.

person Community    schedule 08.10.2014