2013-04-24 1 views
1

셔플해야하는 파일의 중간에 바이트 블록이있는 경우가 있습니다. 현재 구현은 파일을 읽고 메모리의 바이트를 섞은 다음 전체 파일을 출력합니다. 이 기능은 작동하지만 큰 파일 크기에서는 확장되지 않습니다. 나는 C++ API를 찾아야한다. API를 사용하면 특정 바이트 수를 특정 오프셋으로 파일에 기록 할 수있다.어떻게하면 파일의 중간에 바이트를 (다시) 쓸 수 있습니까?

이 작업을 수행 할 수 있습니까?

+1

'seekg'를 사용하고 새로운 위치에 쓰기 만하면됩니다. 이후에 오는 바이트는 영향을받지 않습니다. –

+2

중간에 바이트를 _add_ 또는 _remove_해야한다면 C++ API가 아니라 파일 시스템의 제한 사항입니다. –

답변

4

입력과 출력 모두 수행 중이므로 fstream (ifstream 또는 ofstream이 아님)으로 시작하십시오.

셔플을하려면 기본적으로 변경하려는 위치로 이동하려면 seekg을 사용해야합니다. 그런 다음 셔플 할 데이터를 읽으려면 read을 사용하십시오. 그런 다음 데이터를 메모리에 셔플하고 seekp을 사용하여 해당 데이터를 다시 쓰고 자하는 위치를 찾은 다음 마지막으로 write을 사용하여 셔플 링 된 데이터를 다시 파일에 저장하십시오.

여기에 빠른 데모는 말 그대로 "셔플"참여,의 - 다음에서 일부 데이터를 읽고 그 바이트를 정렬하고 다시 밖으로을 기록,이 파일에 문자열을 씁니다 :

#include <fstream> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <iostream> 

void init(std::string const &name) { 
    std::ofstream initial(name); 

    initial << "This is the initial data."; 
} 

void shuffle(std::string const &name) { 
    std::fstream s(name); 

    s.seekg(2); 
    std::vector<char> data(5); 
    s.read(&data[0], 5); 
    std::sort(data.begin(), data.end()); 
    s.seekp(2); 
    s.write(&data[0], 5); 
} 

void show(std::string const &name) { 
    std::ifstream in(name); 

    std::copy(std::istreambuf_iterator<char>(in), 
       std::istreambuf_iterator<char>(), 
       std::ostream_iterator<char>(std::cout, "")); 
} 

int main() { 
    std::string name("e:/c/source/trash.txt"); 
    init(name); 

    shuffle(name); 

    show(name); 
} 
1

mmap()을 지원하는 플랫폼 (Linux 및 기타 유닉스 좋아요 -하지만 다른 OS에도 유사한 API가 있다고 확신하는 경우, mmap()으로 불리지 않더라도) 파일 ​​(또는 해당 부분)을 매핑하십시오. 그것의)를 당신의 주소 공간에 넣은 다음, 제자리에 섞는다.

관련 문제