Como eu uso basic_filebuf com o elemento tipo diferente de carvão?
Pergunta
Digamos que eu queira ler o conteúdo de um arquivo usando basic_filebuf
. Eu tenho um tipo chamado boost::uintmax_t
que tem um tamanho de 8 bytes
. Eu estou tentando escrever o seguinte:
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++;
}
O problema é que alguns dos bytes
se ler, outros não. Por exemplo, digamos que há 9 bytes
no arquivo 1-9
numeradas:
|1|2|3|4|5|6|7|8|9|
Quando eu executar o código acima, apenas um elemento é empurrado de volta para data
, que contém 4 bytes
apenas a partir dos dados originais em f
:
[0|0|0|0|4|3|2|1] --> only element in [data]
O que estou fazendo de errado? Esta é a minha primeira vez para uso basic_filebuf
diretamente, embora eu saiba como usar filebuf
.
Solução
A basic_filebuf lida com um tipo de char "interna" e outro "externo". A única "externo" é o conteúdo do arquivo, e é sempre bytes. O "interno" é o parâmetro do modelo, e é o utilizado na sua interface com o programa. Para converter entre os dois, basic_filebuf usa a faceta codecvt de sua localidade.
Então, se você quiser escrever diretamente os bytes que você dá, você tem duas opções:
- usar um codecvt "degenerada" que apenas conversões entre os "internos" e codificações "externos" em vez de tentar realizar uma conversão.
- usar um basic_filebuf, certifique-se de usar a localidade "clássico", e fazer o elenco para char-se
Outras dicas
Objectos de basic_filebuf tipo são criado com um tampão interno de tipo CHAR * independentemente do char_type especificado pelo tipo parâmetro Elem. Isto significa que um cadeia Unicode (contendo wchar_t caracteres) será convertido para uma cadeia ANSI (contendo carvão animal caracteres) antes de ser escritos para o tampão interno. Para armazenar Unicode cordas no buffer, criar um novo tampão de tipo wchar_t e configurá-lo usando o basic_streambuf :: pubsetbuf () método.
http://msdn.microsoft.com /en-us/library/tzf8k3z8(VS.80).aspx