拆分二进制文件

时间:2015-03-07 06:10:46

标签: java io binaryfiles

split方法有两个参数,要拆分的文件名和每个拆分的大小。你能检查我是否在写作轨道上吗?还有关于在for循环中输入什么的伪代码?

import java.io.*;

public class SplitFile {

    public static void main(String[] args) throws IOException {
        Split("testfile.pdf", 256);

    }

    public static Split(String filename, int splitSize) throws IOException {

        int numberOfFiles = 0;

        File file = new File(filename);

        numberOfFiles = ((int) file.length() / splitSize) + 1;

        for (; numberOfFiles >= 0; numberOfFiles--) {

            DataInputStream in = new DataInputStream(new BufferedInputStream(
                    new FileInputStream(filename)));

            DataOutputStream out = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(file))); //What do I put here?

        }


    }

}

2 个答案:

答案 0 :(得分:2)

必要的更改

  • 每个输出部分的文件对象,例如
  • 在循环外部初始化数据输入流,而不是在
  • 内部

代码

File original = new File(filename);
int numberOfFiles = ((int) original.length() / splitSize) + 1;

DataInputStream in = 
    new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));

// <== just count through parts.
for (int i = 0; i < numberOfFiles; i++) {
    File output = new File(String.format("%s-%d", filename, i));
    // <== Part of file being output e.g. testfile.pdf-1, testfile.pdf-2

    DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(output)));

}

对于实际写作......

  • 使用read()调用
  • 从输入流中读取字节
  • 使用write()调用
  • 将字节写入输出流

两种方法,一次一个字节 - 最简单,但效率较低,或使用缓冲区,更难编码,但效率更高。

缓冲方法

long length = original.length();

DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));

int pos = 0;
byte[] buffer = new byte[splitSize];
for (...) {
    ...

    // make sure you deal with file not being exactly divisible, 
    // last chunk might be smaller
    long remaining = length - pos;
    in.read(buffer, pos, (int) Math.min(splitSize, remaining));
    out.write(buffer, 0, (int) Math.min(splitSize, remaining));

    pos += splitSize;
}

一次1个字节。

for (...) {
    ...
    for (int i = 0; i < splitSize && pos < length; i++) {
        out.write(in.read());
        pos++;
    }
}

答案 1 :(得分:1)

您可以通过以下方式使用Java NIO API执行此操作。

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public final class SplitFile {

    public static void main(String[] args) throws IOException {
        split("testfile.pdf", 256);
    }

    private static void split(String filename, int splitSize) throws IOException {
        int i = filename.lastIndexOf('.');
        String basename = filename.substring(0, i);
        String ext = filename.substring(i + 1);

        Path inputPath = Paths.get(filename);

        int numberOfFiles = (int) (Files.size(inputPath) / splitSize) + 1;

        try (FileChannel inputChannel = FileChannel.open(inputPath, StandardOpenOption.READ)) {
            for (int j = 0; j < numberOfFiles; j++) {
                String outputFilename = String.format("%s-%04d.%s", basename, j + 1, ext);

                Path outputPath = inputPath.getParent().resolve(outputFilename);

                try (FileChannel outputChannel = FileChannel.open(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
                    inputChannel.transferTo(j * splitSize, splitSize, outputChannel);
                }
            }
        }
    }
}