追加二进制文件的内容

huangapple go评论59阅读模式
英文:

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(&quot;&lt;path to first binary file&gt;&quot;);
InputStream input2 = new FileInputStream(&quot;&lt;path to second binary file&gt;&quot;);
OutputStream  output = new FileOutputStream(&quot;&lt;path to first binary file&gt; &quot;,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, &quot;UTF-8&quot;);
//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(&quot;&lt;path to first binary file&gt;&quot;);
byte[] buffer = new byte[256];
int data;
data = sequenceInputStream.read(buffer);
while(data != -1){
String str = new String(buffer, &quot;UTF-8&quot;);
//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.

huangapple
  • 本文由 发表于 2020年7月22日 01:36:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63020017.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定