3

I'm writing a file transfer protocol, in which files are sent between server and client in packets of 512 bytes each. If a file is larger than that size, the file will be split into multiple packets. I'm doing the splitting ok I think, but I'm having trouble re-assembling the files. If the file is smaller than 512 byte (one packet) the assembly process works, but if the file is larger, only the last packet to arrive is being written to the file.

Here is the code of the 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();
    }
}

}

I think that the fileOutputStream.write(bytes) simply replaces the existing bytes with the new one, what is the alternative to writing into a file?

How do I combine multiple byte[] arrays into a single file?

Thanks in advance :)

3
  • 1
    It's not the write; creating FileOutputStream with the 1-arg String (or File) ctor truncates any existing file. You should create one stream in createFile then write all buffers to that one stream, and then close or at least flush it; in some filesystems not flushing or closing might lose data. Commented Jan 14, 2017 at 19:21
  • You can't rely on < 512 as an EOF indication. A short read can happen at any time, and a file can be a multiple of 512 bytes. You don't need a superimposed packetising protocol just to transfer a file: the standard Java copy loop will do. And you neither need nor want to assemble all the bytes of a file before writing any of it. Unclear what you're asking. Commented Jan 14, 2017 at 19:25
  • See my answer here for the right way to do it. Commented Jan 15, 2017 at 0:09

2 Answers 2

1

Answer to "FileOutputStream simply replaces the existing bytes with the new one, what is the alternative to writing into a file?"

FileOutputStream(File file, boolean append) 

This is the syntax for FileOutputStream so you can put append as true :)

Answer to "How do I combine multiple byte[] arrays into a single file?"

You can use addAll method. Here is an example:

    List<byte[]> listFinal = new ArrayList<byte[]>();
    listFinal.addAll(listA);
    listFinal.addAll(listB);
Sign up to request clarification or add additional context in comments.

Comments

0

You create a new FileOutputStream for every element in your bytesList. Every of those output stream start writing to the file at the start of the file. So you end up overwriting all the bytes until the last element of your bytes-list.

What you want to do is create only one FileOutputStream and use it for all the write(bytes) calls. This way every write will append to the already opened file. Something like that:

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

Also depending on your Java version you can avoid the Iterator by using the for each loop:

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

1 Comment

No reason to construct the list of byte[] in the first place. It just wastes memory. Just write the bytes directly to the file as they are received.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.