ファイルの二分割

でかいファイルを二分割して渡そうと思って、

#!/usr/bin/ruby

path = ARGV.shift
path1 = path + '.1'
path2 = path + '.2'
size = File.size(path)
size1 = size / 2
size2 = size - size1
open(path) do |file|
  open(path1, 'w') do |file1|
    size1.times { file1.putc file.getc() }
  end
  open(path2, 'w') do |file2|
    size2.times { file2.putc file.getc() }
  end
end

こんな風に書いたんだけど、でかいファイルで時間がかかりすぎた。
ということで C に移植。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
	FILE *fp;
	char *path;
	long size, outsizes[2];
	int i;
	if (argc != 2) {
		fprintf(stderr, "Usage: %s filename\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	path = argv[1];
	if ((fp = fopen(path, "r")) == NULL) {
		perror(NULL);
		exit(EXIT_FAILURE);
	}
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	outsizes[0] = size / 2;
	outsizes[1] = size - outsizes[0];
	fseek(fp, 0, SEEK_SET);
	for(i = 0; i < 2; i++) {
		char pathout[512];
		FILE *fpout;
		long j;
		long outsize = outsizes[i];
		sprintf(pathout, "%s.%d", path, i+1);
		if ((fpout = fopen(pathout, "w")) == NULL) {
			perror(NULL);
			exit(EXIT_FAILURE);
		}
		for(j = 0; j < outsize; j++) {
			fputc(fgetc(fp), fpout);
		}
		fclose(fpout);
	}
	fclose(fp);
	return 0;
}

これでなんとかでかいファイルを二分割できた。
でもまだ結構時間かかるなあ。fgetc fputc 使うのがいけないのかしら。 read と write とか使って大きい単位で読み書きしたら速くなるかな?