英文:
Appending content of binary files
问题
我想将一个文件的内容追加到另一个已存在的文件中。我使用了带有追加参数的FileOutputStream以及SequenceInputStream进行普通文件复制。这两种方法对于txt文件都有效,但对于二进制文件如pdf和excel则不起作用。
如果我尝试合并两个pdf文件,总是会覆盖结果文件中的第二个输入流。是否有其他方法可以实现二进制文件的相同操作?
以下是我的代码。
package org.saurav.simpletests.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.SequenceInputStream;
public class ConcatStreams {
    public static void main(String a[]) {
        ConcatStreams concatStreams = new ConcatStreams();
        try {
            InputStream input1 = new FileInputStream("<path to first binary file>");
            InputStream input2 = new FileInputStream("<path to second binary file>");
            OutputStream output = new FileOutputStream("<path to first binary file> ", true);
            //concatStreams.mergeUsingSequenctInputStream(input1,input2); // uncomment it to run the code with sequenceInputStream
            concatStreams.mergeUsingFileOutputAppend(output, input2);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private void mergeUsingFileOutputAppend(OutputStream outStream, InputStream input) {
        try {
            byte[] buffer = new byte[256];
            int data;
            data = input.read(buffer);
            while (data != -1) {
                String str = new String(buffer, "UTF-8");
                //System.out.println(str);
                outStream.write(buffer);
                data = input.read(buffer);
            }
            //output.write(data);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                outStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    private void mergeUsingSequenctInputStream(InputStream input1, InputStream input2) {
        SequenceInputStream sequenceInputStream =
                new SequenceInputStream(input1, input2);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("<path to first binary file>");
            byte[] buffer = new byte[256];
            int data;
            data = sequenceInputStream.read(buffer);
            while (data != -1) {
                String str = new String(buffer, "UTF-8");
                //System.out.println(str);
                fos.write(buffer);
                data = sequenceInputStream.read(buffer);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
最好的问候,
Saurav
英文:
I want to append the content of one file to another existing file with content. I used plain file copy with FileOutputStream with append parameter and also with SequenceInputStream. Both are working for txt files but not for binary files like pdf and excel.
If i try to merge two pdf files always the second input stream is overwritten in the resultant file. Is there any other way i can achieve the same for binary files ?
Below is my code.
package org.saurav.simpletests.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.SequenceInputStream;
public class ConcatStreams {
public static void main (String a[]) {
ConcatStreams concatStreams = new ConcatStreams();
try {
InputStream  input1 = new FileInputStream("<path to first binary file>");
InputStream input2 = new FileInputStream("<path to second binary file>");
OutputStream  output = new FileOutputStream("<path to first binary file> ",true);
//concatStreams.mergeUsingSequenctInputStream(input1,input2); // uncomment it to run the code with sequenceInputStream
concatStreams.mergeUsingFileOutputAppend(output, input2);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void mergeUsingFileOutputAppend(OutputStream outStream, InputStream input) {
try {
byte[] buffer = new byte[256];
int data;
data = input.read(buffer);
while(data != -1){
String str = new String(buffer, "UTF-8");
//System.out.println(str);
outStream.write(buffer);
data = input.read(buffer);
}
//output.write(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void mergeUsingSequenctInputStream(InputStream input1, InputStream input2) {
SequenceInputStream sequenceInputStream =
new SequenceInputStream(input1, input2);
FileOutputStream fos = null;
try {
fos = new FileOutputStream("<path to first binary file>");
byte[] buffer = new byte[256];
int data;
data = sequenceInputStream.read(buffer);
while(data != -1){
String str = new String(buffer, "UTF-8");
//System.out.println(str);
fos.write(buffer);
data = sequenceInputStream.read(buffer);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Best Regards,
Saurav
答案1
得分: 1
你的实现中有一个bug:你总是将固定大小的字节块(等于缓冲区大小)写入输出流,请注意这行代码:
outStream.write(buffer);
请考虑到输入流可能存在小于缓冲区大小的余数。
修复应该使用以下行:
outStream.write(buffer, 0, data);
我已经像这样更新了你的代码,并成功合并了一个分为两部分的JPEG文件。
英文:
There is a bug in your implementation: you always write fixed chunks of bytes (equal to the size of buffer) to output stream, please take attention to this line:
outStream.write(buffer);
Please take into account that input stream might have a remainder that is less than buffer size.
The fix should be using the following line:
outStream.write(buffer, 0, data);
I've updated your code like this and was able to join jpeg file that was split into 2 parts.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论