파일을 안전하고 빠르게 복사하는 방법
조회수 11918회
binary/text 파일을 안전하고 빠르게 복사하는 방법을 찾아보고 있는데요 제가 이때까지 찾아낸 것 외에 다른 분들은 어떻게 쓰는지 궁금합니다
또 제 코드에 문제가 있으면 알려주세요
ANSI-C
#include <iostream>
#include <cstdio> // fopen, fclose, fread, fwrite, BUFSIZ
#include <ctime>
using namespace std;
int main() {
clock_t start, end;
start = clock();
// 기본 BUFSIZE는 8192 bytes
// 1024의 배수는 blocksize에 딱 들어맞고, 큰 값일수록 system call을 줄여 속도가 빨라집니다.
// size_t BUFFER_SIZE = 4096
char buf[BUFSIZ];
size_t size;
FILE* source = fopen("from.ogv", "rb");
FILE* dest = fopen("to.ogv", "wb");
while (size = fread(buf, 1, BUFSIZ, source)) {
fwrite(buf, 1, size, dest);
}
fclose(source);
fclose(dest);
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
POSIX ("The C programming language"에서 K&R이 썼던 방법)
#include <iostream>
#include <fcntl.h> // open
#include <unistd.h> // read, write, close
#include <cstdio> // BUFSIZ
#include <ctime>
using namespace std;
int main() {
clock_t start, end;
start = clock();
// BUFSIZE defaults to 8192
// 1024의 배수는 blocksize에 딱 들어맞고, 큰 값일수록 system call을 줄여 속도가 빨라집니다.
// size_t BUFFER_SIZE = 4096
char buf[BUFSIZ];
size_t size;
int source = open("from.ogv", O_RDONLY, 0);
int dest = open("to.ogv", O_WRONLY | O_CREAT /*| O_TRUNC/**/, 0644);
while ((size = read(source, buf, BUFSIZ)) > 0) {
write(dest, buf, size);
}
close(source);
close(dest);
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
KISS-C++-Streambuffer
#include <iostream>
#include <fstream>
#include <ctime>
using namespace std;
int main() {
clock_t start, end;
start = clock();
ifstream source("from.ogv", ios::binary);
ofstream dest("to.ogv", ios::binary);
dest << source.rdbuf();
source.close();
dest.close();
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
C++ copy 알고리즘
#include <iostream>
#include <fstream>
#include <ctime>
#include <algorithm>
#include <iterator>
using namespace std;
int main() {
clock_t start, end;
start = clock();
ifstream source("from.ogv", ios::binary);
ofstream dest("to.ogv", ios::binary);
istreambuf_iterator<char> begin_source(source);
istreambuf_iterator<char> end_source;
ostreambuf_iterator<char> begin_dest(dest);
copy(begin_source, end_source, begin_dest);
source.close();
dest.close();
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
OWN-BUFFER-C++
#include <iostream>
#include <fstream>
#include <ctime>
using namespace std;
int main() {
clock_t start, end;
start = clock();
ifstream source("from.ogv", ios::binary);
ofstream dest("to.ogv", ios::binary);
// file size
source.seekg(0, ios::end);
ifstream::pos_type size = source.tellg();
source.seekg(0);
// allocate memory for buffer
char* buffer = new char[size];
// copy file
source.read(buffer, size);
dest.write(buffer, size);
// clean up
delete[] buffer;
source.close();
dest.close();
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
LINUX (커널 2.6.33이상)
#include <iostream>
#include <sys/sendfile.h> // sendfile
#include <fcntl.h> // open
#include <unistd.h> // close
#include <sys/stat.h> // fstat
#include <sys/types.h> // fstat
#include <ctime>
using namespace std;
int main() {
clock_t start, end;
start = clock();
int source = open("from.ogv", O_RDONLY, 0);
int dest = open("to.ogv", O_WRONLY | O_CREAT /*| O_TRUNC/**/, 0644);
sendfile(dest, source, 0, stat_source.st_size);
close(source);
close(dest);
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
실행 환경:
GNU/LINUX (Archlinux) Kernel 3.3 GLIBC-2.15, LIBSTDC++ 4.7 (GCC-LIBS), GCC 4.7, Coreutils 8.16 RUN LEVEL 3 사용 (멀티유저, 네트워크, 터미널, gui는 없음) INTEL SSD-Postville 80 GB, 50%사용 중
Program | 설명 | UNBUFFERED | BUFFERED |
---|---|---|---|
ANSI C | fread/frwite | 490,000 | 260,000 |
POSIX | K&R, read/write | 450,000 | 230,000 |
FSTREAM | KISS, Streambuffer | 500,000 | 270,000 |
FSTREAM | Algorithm, copy | 500,000 | 270,000 |
FSTREAM | OWN-BUFFER | 500,000 | 340,000 |
SENDFILE | native LINUX, sendfile | 410,000 | 200,000 |
2 답변
-
제가 아는 방법 중에 여기 안 나와있는 건
int main() { std::ifstream src("from.ogv", std::ios::binary); std::ofstream dst("to.ogv", std::ios::binary); dst << src.rdbuf(); }
정도 인것 같네요. 그리고 이미 C에서 파일 복사와 관련한 헤더 파일
copyfile.h
에 다음 copyfile() 함수가 있는 걸로 알고 있습니다. OS X Man Pages에서int copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);
-
C++ 파일 복사 http://blog.daum.net/andro_java/799 페이지에 Visual Studio 2015에 맞추어 수정한 소스를 올려 두었습니다.
- ANSI-C 264,092바이트 파일 복사(0~2 밀리초) 시간이 정확한지 ... 혹시 시간 나서 보시면 잘못이 있는지 지적 부탁 드립니다. 감사합니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
댓글 입력