2012-05-31 2 views
10

파일을 메모리에 매핑하고 라인별로 구문 분석하려고하는데 istream을 사용해야합니까?istream 대 메모리 매핑 파일?

istream은 파일을 Windows의 메모리에 매핑하는 것과 동일합니까? 나는 파일을 메모리에 매핑하는 완전한 예제를 찾으려고 애를 썼다.

사람들이 msdn에서 메모리 매핑 문서를 링크하는 것을 보았습니다.하지만 누군가가 작은 (~ 15 행?) 예제를 추천 할 수 있다면 저는 가장 환영받을 것입니다.

내가 잘못된 것을 검색해야하지만 Google에서 "C++ 메모리 매핑 예제"를 검색 할 때 반복을 포함하는 예제를 찾을 수 없습니다. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html#ClassSharedMemoryObjectExample

http://msdn.microsoft.com/en-us/library/dd997372.aspx (NO C++ 코드)

http://beej.us/guide/bgipc/output/html/multipage/mmap.html (나는 생각하지 윈도우 유닉스되었다)

+3

"* 파일을 메모리에 매핑하고 ** ** 행별로 구문 분석하려고합니다 *." 파일을 메모리 맵핑하려는 이유를 말씀해 주시겠습니까? 'ifstream'이나'fopen'을 사용하는 것만으로도 한 줄씩 파싱하지 않는 이유는 무엇입니까? –

+3

@Rob, 순전히 성능상의 이유로. 내가 (false?) 인상 아래서 전체 파일을 빠르게 매핑하는 것입니까? – user997112

+2

@ user997112 : 데이터로 수행하는 작업에 따라 다릅니다. 역 추적을 구현하는 적절한 구문 분석기에이 파일을 사용하는 경우 메모리 매핑 된 파일은 빠른 속도로 처리됩니다. 그러나 여러 개의 간단한'std :: getline' 호출과 같이 데이터를 통해 전달을 반복하는 경우 눈에 띄는 차이가있을 것입니다. 가상 주소 공간이 부족하지 않으면 (아마도 GB + 크기 파일이있는 32 비트 코드의 문제 일뿐 아니라) 메모리 매핑 파일을 사용할 때는 _harm_이 없습니다. – ildjarn

답변

11

std::istream :

가장 가까운 결과 (사람들이 내가 보았다 실현 단지 있도록)이었다 추상적 유형 –이므로 직접 사용할 수 없습니다. 대한

#include <cstddef> 
#include <string> 
#include <boost/interprocess/file_mapping.hpp> 
#include <boost/interprocess/mapped_region.hpp> 

namespace bip = boost::interprocess; 

//... 

std::string filename = /*...*/; 
bip::file_mapping mapping(filename.c_str(), bip::read_only); 
bip::mapped_region mapped_rgn(mapping, bip::read_only); 
char const* const mmaped_data = static_cast<char*>(mapped_rgn.get_address()); 
std::size_t const mmap_size = mapped_rgn.get_size(); 

코드 : 메모리 매핑 자체로

#include <cstddef> 
#include <string> 
#include <streambuf> 
#include <istream> 

template<typename CharT, typename TraitsT = std::char_traits<CharT>> 
struct basic_membuf : std::basic_streambuf<CharT, TraitsT> { 
    basic_membuf(CharT const* const buf, std::size_t const size) { 
     CharT* const p = const_cast<CharT*>(buf); 
     this->setg(p, p, p + size); 
    } 

    //... 
}; 

template<typename CharT, typename TraitsT = std::char_traits<CharT>> 
struct basic_imemstream 
: virtual basic_membuf<CharT, TraitsT>, std::basic_istream<CharT, TraitsT> { 
    basic_imemstream(CharT const* const buf, std::size_t const size) 
    : basic_membuf(buf, size), 
     std::basic_istream(static_cast<std::basic_streambuf<CharT, TraitsT>*>(this)) 
    { } 

    //... 
}; 

using imemstream = basic_imemstream<char>; 

char const* const mmaped_data = /*...*/; 
std::size_t const mmap_size = /*...*/; 
imemstream s(mmaped_data, mmap_size); 
// s now uses the memory mapped data as its underlying buffer. 

, 나는이 목적을 위해 Boost.Interprocess을 사용하는 것이 좋습니다 : 당신은 배열 백업 streambuf 정의와 그것에서 파생해야한다 imemstreamthis answer에서 취한 Dietmar Kühl입니다.

+2

mmaped_data의 입력은 어디서 오는 것입니까? 내가 상상하는 파일에 대한 참고가 필요합니까? – user997112

+1

@ user997112 : 현재 사용중인 플랫폼에 따라 다릅니다. 표준 C++은 메모리 매핑 파일을 제공하지 않습니다. * nix에는 'mmap'이있다. Windows에는'CreateFileMapping'이 있습니다. 개인적으로, 저는 크로스 플랫폼이기 때문에 [Boost.Interprocess] (http://www.boost.org/libs/interprocess/)의 메모리 매핑 파일을 사용합니다. 나는 그 예를 편집 할 것이다. – ildjarn

+0

고맙습니다. 대단히 감사합니다. – user997112

1

istream은 파일을 Windows의 메모리에 매핑하는 것과 동일합니까?

정확하게는 아닙니다. 같은 의미에서 "스트림"은 "파일"이 아닙니다.

파일을 저장 시퀀스로, 저장소에서 수신 변수로 이동할 때 시퀀스가 ​​흐르는 "채널"(stream_buffer)의 인터페이스로 스트림을 생각해보십시오.

메모리 매핑 된 파일을 처리 장치 외부에 저장되어있는 "파일"로 생각하면 메모리에 동기화되어 저장됩니다. 파일이되는 원시 메모리 버퍼로 볼 수있는 장점이 있습니다. 스트림으로 읽으려면 가장 간단한 방법은 원시 버퍼를 읽을 곳으로 사용하는 istringstream을 사용하는 것입니다.

+0

솔직히 말해서 나는 스트림 전체가 아닌 한 번에 전체 파일을 읽는 편이 낫다. – user997112

+0

@ user997112 : 내용으로 무엇을 할 것인가에 달려있다. 파일이 텍스트이고 숫자를 읽어야하는 경우 어떻게 든 구문을 분석해야합니다. std :: istream (파생 된)은 파서입니다. –

관련 문제