Как использовать basic_filebuf с типом элемента, отличным от char? - PullRequest
4 голосов
/ 14 сентября 2009

Скажите, что я хочу прочитать содержимое файла, используя basic_filebuf. У меня есть тип с именем boost::uintmax_t, который имеет размер 8 bytes. Я пытаюсь написать следующее:

typedef basic_filebuf<uintmax_t> file;
typedef istreambuf_iterator<uintmax_t> ifile;

file f;
vector<uintmax_t> data, buf(2);

f.open("test.txt", std::ios::in | std::ios::binary);
f.pubsetbuf(&buf[0], 1024);

ifile start(&f), end;
while(start != end)
{
    data.push_back(*start);
    start++;
}

Проблема в том, что некоторые из bytes читаются, другие нет. Например, допустим, в файле пронумеровано 9 bytes 1-9:

|1|2|3|4|5|6|7|8|9|

Когда я запускаю приведенный выше код, только один элемент возвращается в data, который содержит 4 bytes только из исходных данных в f:

[0|0|0|0|4|3|2|1] --> only element in [data]

Что я делаю не так? Я впервые использую basic_filebuf напрямую, хотя я знаю, как использовать filebuf.

Ответы [ 2 ]

4 голосов
/ 15 сентября 2009

basic_filebuf имеет дело с «внутренним» типом символа и «внешним» типом. «Внешний» является содержимым файла и всегда является байтом. «Внутренний» является параметром шаблона и используется в его интерфейсе с программой. Для преобразования между ними basic_filebuf использует фасет codecvt своей локали.

Так что, если вы хотите, чтобы он записывал непосредственно байты, которые вы ему дали, у вас есть два варианта:

  • использовать "вырожденный" кодеквт, который выполняет преобразование только между "внутренним" и "внешним" кодировками, а не пытаться выполнить преобразование.
  • используйте basic_filebuf, убедитесь, что вы используете "классическую" локаль, и выполните приведение к себе
0 голосов
/ 14 сентября 2009

Объекты типа basic_filebuf создан с внутренним буфером введите char * независимо от тип char_type, указанный типом параметр Elem. Это означает, что Строка Unicode (содержащая wchar_t символы) будут преобразованы в Строка ANSI (содержит символ символы), прежде чем он будет написан внутренний буфер. Хранить Юникод строки в буфере, создайте новый буфер типа wchar_t и установите его используя basic_streambuf :: pubsetbuf () способ.

от http://msdn.microsoft.com/en-us/library/tzf8k3z8(VS.80).aspx

...