英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论