ファイルの二分割
でかいファイルを二分割して渡そうと思って、
#!/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 とか使って大きい単位で読み書きしたら速くなるかな?