2017-01-14 3 views
0

Я пишу протокол передачи файлов, в котором файлы отправлены между сервером и клиентом в пакетах по 512 байт каждый. Если файл больше указанного размера, файл будет разбит на несколько пакетов. Я делаю расщепление нормально, я думаю, но у меня возникли проблемы с повторной сборкой файлов. Если файл меньше 512 байт (один пакет), процесс сборки работает, но если файл больше, в файл записывается только последний пакет.Объединение нескольких байт [] массивов в один файл

Вот код FileAssembler:

public class FileAssambler { 

List<byte[]> bytesList; 
private String name; 
boolean finished=false; 
private FileOutputStream fileOutputStream; 

public FileAssambler(String name){ 
    bytesList = new ArrayList<byte[]>(); 
    this.name = name; 
} 

public void addBytes(byte[] bytes){ 
    if(bytes.length<512) 
     finished=true; 
    bytesList.add(bytes); 
} 

public boolean isFinished(){ 
    return finished; 
} 

public void createFile() throws IOException{ 
    Iterator<byte[]> it = bytesList.iterator(); 
    while(it.hasNext()) 
     writeBytesToFile(it.next()); 
} 

private void writeBytesToFile(byte[] bytes){ 

    try{ 
     fileOutputStream = new FileOutputStream(name); 
     fileOutputStream.write(bytes); 
    }catch(IOException e){ 
     e.printStackTrace(); 
    } 
} 

}

Я думаю, что fileOutputStream.write (байт) просто заменяет существующие байты с новым, что является альтернативой письменной форме в файл?

Как объединить массивы с несколькими байтами [] в один файл?

Заранее спасибо :)

+0

Это не «написать»; создание 'FileOutputStream' с 1-arg String (или File) ctor ** усекает любой существующий файл **. Вы должны создать _one_ stream в 'createFile', затем' write' _all_ буфера для этого потока, а затем 'закрыть 'или, по крайней мере,' flush' it; в некоторых файловых системах, которые не смываются или не закрываются, могут потерять данные. –

+0

Вы не можете полагаться на '<512' в качестве индикатора EOF. Короткое чтение может произойти в любое время, а файл может быть кратным 512 байт. Для передачи файла вам не требуется наложенный пакетный протокол для передачи файла: стандартный цикл копирования Java будет выполняться. И вам не нужно и не хотите собирать все байты файла, прежде чем писать какие-либо из них. Неясно, что вы спрашиваете. – EJP

+0

Посмотрите мой ответ [здесь] (http://stackoverflow.com/questions/10367698/java-multiple-file-transfer-over-socket) для правильного пути его выполнения. – EJP

ответ

0

Вы создаете новый FileOutputStream для каждого элемента в вашем bytesList. Каждый из этих выходных потоков начинает записывать в файл в начале файла. Таким образом, вы переписываете все байты до последнего элемента вашего списка байтов.

То, что вы хотите сделать, это создать только один FileOutputStream и использовать его для всех write(bytes) вызовов. Таким образом, каждый write добавит к уже открытому файлу. Нечто подобное:

public void createFile() throws IOException{ 
    FileOutputStream fos = new FileOutputStream(name); 
    Iterator<byte[]> it = bytesList.iterator(); 
    while (it.hasNext()) 
     fos.write(it.next()); 
} 

Также в зависимости от версии Java вы можете избежать Iterator, используя для каждого цикла:

public void createFile() throws IOException { 
    FileOutputStream fos = new FileOutputStream(name); 
    for (byte[] data: bytesList) 
     for.write(data); 
} 
+0

Спасибо, что решил! – Dolav

0

Ответ на «FileOutputStream просто заменяет существующие байты с новым, что является альтернативой написанию в файл? "

FileOutputStream(File file, boolean append) 

Это синтаксис для FileOutputStream, так что вы можете поместить добавить в настоящий :)

ответа на «Как объединить несколько байт [] массивов в один файл?»

Вы можете использовать метод addAll. Вот пример:

List<byte[]> listFinal = new ArrayList<byte[]>(); 
    listFinal.addAll(listA); 
    listFinal.addAll(listB);