[C++] File IO : <ifstream> 과 pubsetbuf()
``c ifstream``을 사용할지, ``c fopen()``을 사용할지는 얻어낸 결과를 어디에 담을 것인지에 따라 결정하면 된다.
어차피 얻어낸 데이터를 가공하는 과정에서 `` string``으로 만들어야 한다거나, `` string``의 메서드를 사용해야 편한 경우라면 그냥 `` ifstream``을 사용한다.
왜냐면, ``c char*``에서 `` string``으로 변환하는건 새로운 `` string``을 만들면서 생성자로 ``c char*``데이터를 집어넣는 수 밖에 없는데 이 때 Deep copy가 발생한다.
Shallow copy하는 방법 없나 찾아봤는데 아마 없는 것 같다.
그래서 문자열 데이터가 큰 경우 copy시 발생하는 오버헤드를 줄일 필요가 있기 때문에 아예 가공할 데이터의 타입을 따라가는 것이 좋다.
```cpp
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
ifstream ifs;
char buf[USER_BUFSIZ];
ifs.rdbuf()->pubsetbuf(buf, USER_BUFSIZ); // setbuf before open().
ifs.open("C:\\Users\\umbum\\source\\repos\\a", std::ios::binary);
if (ifs.fail()) {
std::cout << "[*] failed to open" << std::endl;
exit(EXIT_FAILURE);
}
filebuf* pbuf = ifs.rdbuf();
// pbuf->pubsetbuf(buf, BUF_SIZE); 이렇게 해도 되고
// ifs.rdbuf()->pub..이렇게 해도 되나 ifs.getline()을 쓸 경우는 이게 낫고, pbuf->sgetn()을 쓸거면 위가 낫다.
// 이렇게 버퍼를 지정해 놓기만 하면, getline()이든 sgetn()이든 접근 시 알아서 버퍼를 채우고, 버퍼에서 가져오는 듯.
// 아직 데이터에 접근하지는 않았으니 여기서는 모두 00이 출력된다.
for (int i = 0; i < BUF_SIZE; i++) {
printf("%02x ", buf[i]);
}
cout << "\n==============================================" << endl;
char b4[4];
pbuf->sgetn(b4, 4); // 이 때 1. buf에 데이터가 채워지고, 2. b4에 데이터가 copy된다.
// pbuf->sgetn() 를 반복적으로 호출해주면 offset이 증가하며 알아서 다음 데이터를 가져온다.
// ifs.getline() 도 버퍼에서 가져오기 때문에 buffer를 사용하기 위해 꼭 sgetn()일 필요는 없다.
// pbuf->pubseekoff(-4, ifs.cur); 현재 위치 기준 뒤로 감기는 이렇게.
printf("%02x%02x%02x%02x", b4[0], b4[1], b4[2], b4[3]); // 데이터 있다.
for (int i = 0; i < BUF_SIZE; i++) {
printf("%02x ", buf[i]);
} // 여기도 채워져 있다.
ifs.close();
return 0;
}
'Languages & Frameworks > C C++' 카테고리의 다른 글
[C++] directory listing (traversal) (0) | 2018.08.10 |
---|---|
[C/C++] clock : 수행 시간 측정 / logging : 에러 출력 (0) | 2018.08.09 |
[C/C++]의 동적 할당과 Memory leak (0) | 2018.06.11 |
[C] system V IPC (0) | 2017.11.10 |
[C] dll을 이용한 메모리(데이터) 공유 (0) | 2017.11.10 |