Feb 3rd 2010, 23:04
Aprenda a armazenar o conteúdo de uma struct em um arquivo.
Hoje vamos aprender um pouco sobre o processo de
serialização, algumas de suas aplicações em jogos e um exemplo de implementação.
Serialização é um processo em que basicamente convertemos um objeto, estrutura de dados ou grupo de objetos em uma stream (sequencia) de bits para uso posterior (por exemplo para ser armazenado em um arquivo, buffer de memória ou transmitido em rede conforme diagrama a seguir:
Aplicações em jogos
O processo de serialização possui diversas aplicações em jogos eletrônicos, sendo duas muito úteis:
- armazenamento do estado do jogo para posterior carregamento (save&load game);
- conversão de estruturas para transmissão através da rede (jogos multiplayer).
Exemplo de implementação
Vamos aplicar um exemplo simples de serialização em C.
Em partes, precisamos verificar:
- o que iremos armazenar;
- onde iremos armazenar;
- como iremos armazenar.
1. o que iremos armazenar: vamos armazenar o conteúdo de uma
struct de tipo
configuration_values_t que criaremos a seguir;
2. onde iremos armazenar: os bytes desta struct serão armazenados em um arquivo
config.dat no mesmo diretório em que o nosso executável for chamado.
3. como iremos armazenar: vamos utilizar algumas funções padrões da biblioteca padrão do ANSI C, em especial as funções
fwrite e
fread
Com isso em mente crie um arquivo chamado
main.c e insira o esqueleto abaixo:
Agora vamos criar a struct que irá armazenar o conteúdo que queremos (acima da função main, linha 5):
Aqui temos uma struct de tipo
configuration_values_t onde iremos armazenar os valores que queremos serializar.
Note que não temos nenhum ponteiro no conteúdo da struct (mais sobre isso a seguir).
Agora vamos para as funções de salvamento e carregamento:
Com essas duas funções podemos criar um struct do tipo
configuration_values_t, ler e armazenar seus valores em um arquivo no disco.
Um exemplo completo na função main:
Este exemplo conclui a implementação.
Se quiser o código fonte do projeto baixe a seguir (arquivo de projeto no formato Visual C++ Express Edition 2008).

Código fonte do projeto de serialização
Problemas
Apesar de ser relativamente fácil, o processo de serialização possui algumas características que devem ser observadas com atenção:
- endianess: ao se trocar dados entre máquinas diferentes, é possível que elas armazenem as sequencias de forma diferente (invertendo os bytes em determinados casos), isso deve ser levado em consideração nos jogos multiplayers.
- ponteiros: ao transformar ponteiros em uma sequencia, deve-se observar que ao se executar o processo inverso os ponteiros poderão apontar para referências inválidas sendo o mais recomendável serializar o conteúdo do ponteiro ao invés disso;
- versionamento: ao se carregar uma struct de um arquivo, corremos o risco da representação não ser exata se tivermos alterado a estrutura da struct e o arquivo utilizar uma estrutura antiga, podendo ocasionar corrompimento nos valores e possíveis problemas não previsíveis.
Conclusão
Serialização é um processo muito útil, existem ainda outras aplicações para a técnica como por exemplo serializar uma estrutura de arquivos e diretórios para a memória, etc
O artigo foi escrito com um exemplo em C, mas em C++ é ainda mais fácil (veja as referências para um exemplo de implementação).
Referências
Para entender melhor o processo, consulte alguns dos links abaixo: