Duvida sobre TStringList + .ini

119 views
Skip to first unread message

.Marcelo de Souza (MAPIS)

unread,
Dec 4, 2009, 6:27:28 AM12/4/09
to ccppb...@googlegroups.com
Bom dia galera,

eu estou com um probleminha com o TStringList lendo um arquivo .ini, o problema está que ele só consegui ler 1820 section do arquivo .ini

Gostaria de saber se tem alguma maneira de configurar isso para ele poder ler o arquivo inteiro...

aqui uma parte do meu codigo:

TIniFile *arquivoLeitura = new TIniFile(GetCurrentDir() + "\\teste.INI");

TStringList* Ts = new TStringList;

for(int i=0; i < Ts->Count; i++){
    ListBox1->Items->Add(Ts->String[i]);
}

agradeço a todos,

abraços

--
========================
Marcelo P. de Souza ( MAPIS )
========================

Gianni

unread,
Dec 4, 2009, 7:07:26 AM12/4/09
to ccppb...@googlegroups.com
Vc ta usando C-Builder da borland né?  enfim...  vc lê o arquivo com o objeto 'arquivoLeitura', e depois não usa mais objeto?

Marcio Gil

unread,
Dec 4, 2009, 8:08:49 AM12/4/09
to ccppb...@googlegroups.com
> -----Original Message-----
> From: .Marcelo de Souza (MAPIS)
>
> Bom dia galera,
>
> eu estou com um probleminha com o TStringList lendo um arquivo
> .ini, o problema está que ele só consegui ler 1820 section do
> arquivo .ini
>
> Gostaria de saber se tem alguma maneira de configurar isso para
> ele poder ler o arquivo inteiro...
>
> aqui uma parte do meu codigo:
>
> TIniFile *arquivoLeitura = new TIniFile(
> GetCurrentDir() + "\\teste.INI");
>
> TStringList* Ts = new TStringList;
>

Até aqui tudo bem, você criou um objeto TIniFile e uma lista de
strings. Agora o que você quer? Ler os nomes das seções?

Neste caso utilize o método ReadSections:

<<<
Reads the names of all sections in an INI file into a string
list.

virtual void __fastcall ReadSections(Classes::TStrings* Strings);
>>>

Assim:

arquivoLeitura->ReadSections( Ts );

> for(int i=0; i < Ts->Count; i++){
> ListBox1->Items->Add(Ts->String[i]);
> }
>
> agradeço a todos,
>
> abraços
>

Se não for bem isso, então nos explique um pouco mais.

Marcio Gil.

.Marcelo de Souza (MAPIS)

unread,
Dec 4, 2009, 10:53:32 AM12/4/09
to ccppb...@googlegroups.com
Então galera,

Eu estou usando C++ Builder 6.

O que eu estou com problema é o seguinte... eu só consigo ler 1820 section do arquivo que tem mais de 3800 section, então eu queria poder ler tudo e fazer a inversão dos arquivo... eu tenho a section, name e value em cada .ini , eu só quero inverter o valeu pelo section... mas isso já está sendo feito... o problem é a quantidade que está lendo, eu tentei usar o Capacity mas não funcionou!

sim, eu já estava usando esse readSections...

o que eu acho estranho é ele achar só 1820 section de um arquivo que tem muito mais que isso!!

valeu ai pessoal...

abraços

2009/12/4 Marcio Gil <marci...@bol.com.br>

Gianni

unread,
Dec 4, 2009, 11:17:59 AM12/4/09
to ccppb...@googlegroups.com
hehe... eu diria que é estranho vc precisar mais que 1820 sections...

Arquivo .ini não foi projetado para isso, e portanto, nem o TIniFile deve ter sido.

Minha sugestão é que vc abandone o TIniFile completamente, e leia o arquivo usando um std::ifile ou algo semelhante.  Dada a sua necessidade específica, o TIniFile não vai dar conta.  Na verdade, uma pergunta que tem precedencia é: precisa ser ini mesmo?  Com esse tamanho, ini não é uma opção tão boa.  XML/SAX seria melhor.

Ronaldo Faria Lima

unread,
Dec 4, 2009, 12:21:10 PM12/4/09
to ccppb...@googlegroups.com
Complementando a sugestão do Gianni:

Os arquivos .ini são bons para pequenas configurações. Quando o volume
de dados é muito grande, é interessante optar pelo formato XML, ou por
um banco de dados SQLite.

O formato XML tem a vantagem de permitir uma boa estruturação das sua
informação e a desvantagem de exigir um pouco no processamento das
diretivas, principalmente se você fizer o parsing de maneira a gerar um
DOM. A biblioteca EXPAT é simples e tem uma performance absurda, apesar
de exigir um pouco mais de trabalho de programação.

O SQLite é um banco de dados muito simples, com uma API extremamente
simples de ser usada. As aplicações do projeto Mozilla o utilizam para
persistências de configurações. A vantagem é o acesso rápido aos dados,
sem falar na possibilidade de usar o modelo relacional para organizar
sua informação.

Espero ter ajudado.

Ronaldo

Gianni escreveu:
> hehe... eu diria que é estranho vc precisar mais que 1820 sections...
>
> Arquivo .ini não foi projetado para isso, e portanto, nem o TIniFile
> deve ter sido.
>
> Minha sugestão é que vc abandone o TIniFile completamente, e leia o
> arquivo usando um std::ifile ou algo semelhante. Dada a sua necessidade
> específica, o TIniFile não vai dar conta. Na verdade, uma pergunta que
> tem precedencia é: precisa ser ini mesmo? Com esse tamanho, ini não é
> uma opção tão boa. XML/SAX seria melhor.
>
>
> On Dec 4, 2009, at 1:53 PM, .Marcelo de Souza (MAPIS) wrote:
>
>> Então galera,
>>
>> Eu estou usando C++ Builder 6.
>>
>> O que eu estou com problema é o seguinte... eu só consigo ler 1820
>> section do arquivo que tem mais de 3800 section, então eu queria poder
>> ler tudo e fazer a inversão dos arquivo... eu tenho a section, name e
>> value em cada .ini , eu só quero inverter o valeu pelo section... mas
>> isso já está sendo feito... o problem é a quantidade que está lendo,
>> eu tentei usar o Capacity mas não funcionou!
>>
>> sim, eu já estava usando esse readSections...
>>
>> o que eu acho estranho é ele achar só 1820 section de um arquivo que
>> tem muito mais que isso!!
>>
>> valeu ai pessoal...
>>
>> abraços
>>
>> 2009/12/4 Marcio Gil <marci...@bol.com.br
>> <mailto:marci...@bol.com.br>>
>>
>>
>> > -----Original Message-----
>> > From: .Marcelo de Souza (MAPIS)
>> >
>> > Bom dia galera,
>> >
>> > eu estou com um probleminha com o TStringList lendo um arquivo
>> > .ini, o problema está que ele só consegui ler 1820 section do
>> > arquivo .ini
>> >
>> > Gostaria de saber se tem alguma maneira de configurar isso para
>> > ele poder ler o arquivo inteiro...
>> >
>> > aqui uma parte do meu codigo:
>> >
>> > TIniFile *arquivoLeitura = new TIniFile(
>> > GetCurrentDir() + "\\teste.INI <smb://teste.INI>");

.Marcelo de Souza (MAPIS)

unread,
Dec 4, 2009, 12:34:19 PM12/4/09
to ccppb...@googlegroups.com
Obrigado pelas respostas galera, estão me ajudando mesmo

bom, sobre o problema, na verdade esse arquivo .ini ja vem de um outro projeto e agora precisamos dele...

Sobre mudar, eu vou tentar mostrar esse opção para meu chefe, sou estagiario e porisso ele ainda não me dá muita moral =), mas vou ver com ele, quando falamos em usar bd ele não aceitou a um tempo atrás, vamos ver se ao menos XML ele aceite!!

Esse INI demora demais para ser lido e convertido... realmente não é uma boa opção para essa aplicação em especifico..

Obrigado pessoal pelas dicas, se eu conseguir resolver de alguma maneira eu posto aqui, mas vou continuar procurando

abraços

2009/12/4 Ronaldo Faria Lima <ronaldo.f...@gmail.com>

Marcio Gil

unread,
Dec 4, 2009, 12:56:58 PM12/4/09
to ccppb...@googlegroups.com
Como o colega Gianni falou, o TIniFile não foi feito para este
volume de dados. Talvez você possa contornar isto, até encontrar
uma solução mais adequada, utilizando somente a TStringList ou
lendo o arquivo diretamente. Eu juntei vários arquivos INI e
depois dupliquei 2 ou 3 vezes, até conseguir um arquivo INI com
mais de 4000 seções, e fiz um pequeno teste:

TIniFile *arquivoLeitura = new TIniFile(
GetCurrentDir() + "\\teste.INI");
TStringList* Ts = new TStringList;

arquivoLeitura->ReadSections( Ts );

std::cout << "Encontradas "
<< Ts->Count << " seções." << std::endl;

Ts->LoadFromFile( GetCurrentDir() + "\\teste.INI" );
int nsections = 0;
for (int i = 0; i < Ts->Count; ++i)
{ if (Ts->Strings[i].c_str()[0] == '[')
++nsections;
}

std::cout << "Encontradas " << nsections << " seções." <<
std::endl;
getchar();

delete arquivoLeitura;
delete Ts;

O resultado foi:

Encontradas 887 seções.
Encontradas 4052 seções.

Obviamente o TIniFile não fez o trabalho, mas o TStringList fez.

Gianni

unread,
Dec 4, 2009, 12:58:48 PM12/4/09
to ccppb...@googlegroups.com
Justamente eu falei em XML caso vc pudesse mudar isso.  E complementando o complemento do Ronaldo, eu diria que dependendo do problema, melhor que SQLite seria ProtocolBuffer:


A vantagem do pb é que é muito mais simples que SQLite, logo o tamanho do arquivo e custo de processamento e armazenamento/transmissão é muito menor.  Não é relacional como o SQLite, mas vai ser muito melhor que ini.

Por acaso, eu uso com frequência XML, SQLite e ProtocolBuffers.  Uso XML só quando preciso fazer uma interface com outro programa, afinal é o denominador commun em TI.  SQLite é usado para dados 'internos' das minhas apps.  Para todo dado transmitido via rede, uso protocol buffer pela eficiência, facilidade de uso e type-safety do processo.  Cada ferramenta tem sua utilidade; vc precisa conhecer todas e saber quando cada uma resolve melhor o seu problema.  Nenhuma vai ser sempre a melhor solução.

Ronaldo Faria Lima

unread,
Dec 4, 2009, 1:10:24 PM12/4/09
to ccppb...@googlegroups.com
Gianni,

acabei de me lembrar de uma coisa antiquíssima e que é excelente para o
caso do Marcelo: DBM. Como ele está trabalhando no Windows, talvez fosse
o caso de obter o código do GDBM e utilizá-lo no projeto.

Trata-se de uma lib antiga que já foi amplamente testada e é eficiente
para esses casos.

Bem, aqui está mais uma opção.

Abraços,

Ronaldo

Gianni escreveu:
>> <mailto:ronaldo.f...@gmail.com>>
>> >> <mailto:marci...@bol.com.br <mailto:marci...@bol.com.br>>>

Gianni

unread,
Dec 4, 2009, 1:19:25 PM12/4/09
to ccppb...@googlegroups.com
hehe... eu estou de certa forma falando tudo meio por cima, com um pé atrás antes de falar algo definitivo pois justamente não conheço nada o ambiente Windows. A última vez que mexi com ele, foi com o Delphi (por isso que eu disse que o TIniFile tinha limitações, pq vi isso no Delphi), e foi a muuuuito tempo atrás. Quem sabe alguém que conheça melhor o windows tenha uma idéia como a sua, mais 'nativa' da plataforma...

Gianni

unread,
Dec 4, 2009, 1:31:10 PM12/4/09
to ccppb...@googlegroups.com
Bom, agora que li sobre o GDBM, eu digo que ele tem um suposto problema que seria o mesmo que eu teria com o SQLite. Não me entenda errado, eu uso *muito* o SQLite, mas nunca para transmitir dados (que parece ser o caso aqui). Para armazenar, processar, etc... BDs são muito bons, mas eles não foram desenhados para transmitir, assim vc pode sofrer com um lado não conseguir ler o arquivo direito, ser menos resistente a corrupção (vc viu a história do Mensalão do Oracle!! nem te conto!). etc...

Já o ProtocolBuffer e o XML foram denhados para isso. Logo, tem recursos p/ garantir que o dados seja transmitido corretamente, que geralmente significa fazer controle correto do characterset (que SQLite não faz), é econômico no tamanho (BDs tem páginas de dados que não são usadas, indices que geralmente não fazem sentido na transmissão) etc...etc..

On Dec 4, 2009, at 4:10 PM, Ronaldo Faria Lima wrote:

>

Ronaldo Faria Lima

unread,
Dec 4, 2009, 1:44:27 PM12/4/09
to ccppb...@googlegroups.com
Confesso que não entendi seu ponto. Transmitir dados? Até onde é do meu
domínio de conhecimento, banco de dados é uma solução para armazenamento
e busca de informações e não transmissão. Transmissão envolve problemas
de tamanho de palavras binárias e ordens de bits (endians), que podem
variar de arquitetura para arquitetura. Não entendo como alguém possa
usar um banco de dados para este fim.

Você poderia elaborar melhor seu ponto-de-vista? Acho que isso irá
enriquecer essa discussão.

Abraços,

Ronaldo

Gianni escreveu:

Gianni

unread,
Dec 4, 2009, 2:07:50 PM12/4/09
to ccppb...@googlegroups.com
'Transmitir dados' no sentido que o dado é gerado por uma aplicação e consumido por outra. Era isso que eu queria dizer... realmente não foi uma escolha tão boa, mas não achei um termo melhor. E, veja que eu disse justamente que BDs *não servem* para isso.

Falando em transmissão, tamanhos de palavras e endiness são sim questões, mas não as únicas. Note que no post original não foi dito a origem do arquivo ini. Pode ter sido gerado em outra máquina ou não. Pode ter sido gerado com UTF-16, ou com CRLF (ao invés de só LF ou só CR), etc etc...

XML é desenhado para abstrair isso. Ele tem um header que diz que charset foi usado (geralmente ASCII ou UTF-8) e uma boa biblioteca XML traduz isso automáticamente. Ele máscara fin-de-liha (CRLF ou LF). É totalmente indiferente a tamanhos de palavras e ordens de bits, etc. Ele foi desenhado para isso.

BDs geralmente adotam endiness e tamanho de palavras nativos; logo só servem em uma plataforma. A maioria deles trabalham com 'páginas de dados', ou seja, para transmitir 1,2 ou 8000 bytes, vc sempre vai usar 10k por exemplo. Podem utilizar versões específicas de bibliotecas do sistema que afetam como os dados são lidos e escritos (eu exemplo que eu conheço é o Firebird com uso do ICU - se vc leva um banco de um lugar a outro que tenham ICUs diferentes, os indices param de funcionar em alguns casos).

Rodrigo (skhaz)

unread,
Dec 4, 2009, 2:10:13 PM12/4/09
to ccppb...@googlegroups.com
Por falar em 'Transmitir dados', alguem aqui já uso a biblioteca protobuf?

2009/12/4 Gianni <nasus....@gmail.com>



--
http://www.wintermoonframework.org/

Rodrigo (skhaz)

unread,
Dec 4, 2009, 2:13:39 PM12/4/09
to ccppb...@googlegroups.com
correção, a protobuf não faz 'transmição de dados' apenas serialização.

2009/12/4 Rodrigo (skhaz) <rodrigo...@gmail.com>



--
http://www.wintermoonframework.org/

Gianni

unread,
Dec 4, 2009, 2:14:36 PM12/4/09
to ccppb...@googlegroups.com
como já disse: eu.  :-)

Gianni

unread,
Dec 4, 2009, 2:17:31 PM12/4/09
to ccppb...@googlegroups.com
Bom, complementando então... eu tinha uma solução rodando em um processador embdded (MIPS) que usava boost::asio + SSL + SOAP.

Troquei o SOAP por protocol buffers.  Ficou jóia!
Reply all
Reply to author
Forward
0 new messages