Pra estrear a página sobre programação, neste breve tutorial abordarei os conceitos e os passos necessários para trabalhar com arquivos INI pelo Delphi. Em uma breve explicação, a principal função de um arquivo INI é armazenar dados básicos de configuração da aplicação por meio de seções e valores, muito utilizado por desenvolvedores atualmente.
Por quê utilizar arquivos INI?
Vamos supor que temos um sistema para emissão de pedidos, e uma das funções deste sistema é gravar os arquivos PDF dos pedidos emitidos em uma pasta no computador, para que depois o usuário possa enviá-los aos seus clientes. No código-fonte do sistema, definimos a pasta de armazenamento dos arquivos PDF como C:\Aplicativo\PDF
, conforme solicitado pelo usuário.
Porém, alguns meses depois, o usuário decide comprar um disco externo para armazenar estes arquivos PDF. Mas espere aÃ, o nosso sistema somente aceita gravar os arquivos no diretório C:\Aplicativo\PDF
, não é? Portanto, a única solução é abrir o código-fonte, alterar a pasta de armazenamento, compilar o software e atualizá-lo no computador do usuário. Ok, é uma solução, mas e se futuramente ele decidir alterar a pasta de armazenamento novamente?
Este é um tipo de situação comum no cenário de desenvolvimento de software. No exemplo acima, é possÃvel contornar este problema utilizando um arquivo do tipo INI para armazenar o diretório da gravação dos pedidos. Dessa forma, essa e outras configurações do software são armazenadas externamente, e podem ser editadas sem a necessidade de manutenção no sistema, e melhor, dispensando a gravação de parâmetros no banco de dados.
Como se define um arquivo INI?
Por armazenar um conteúdo de configuração, o arquivo INI possui uma estrutura padrão constituÃda de seções, propriedades e valores.
- As seções representam agrupamentos de valores, ou seja, o assunto no qual se destina os valores armazenados.
- As propriedades são os nomes das configurações que deseja-se armazenar.
- Os valores, como o próprio nome diz, armazenam os dados das configurações.
Para esclarecer melhor, a estrutura do arquivo INI é exemplificada no código abaixo:
1 2 3 4 5 6 7 8 9 10 |
[Seção 1] Propriedade1=Valor1 Propriedade2=Valor2 Propriedade3=Valor3 [Seção 2] Propriedade1=Valor1 . . . |
Utilizando a situação acima como exemplo, poderÃamos definir o arquivo INI da seguinte forma:
1 2 |
[Configuracao] DiretorioPDF=C:\Aplicativo\PDF |
Observe que forneci um nome sugestivo para a seção e para a propriedade, para que depois fique mais fácil para acessá-las pelo Delphi.
Gravando arquivos INI
Agora que conhecemos o que é um arquivo INI, sua função e estrutura, basta escrevermos os métodos necessários para ler e gravar dados pelo Delphi. O primeiro passo é declarar a referência IniFiles
na cláusula uses da unit, conforme o código abaixo. Este passo é necessário para que o Delphi reconheça os métodos que usaremos para manipular o arquivo INI.
1 2 3 |
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IniFiles; |
Insira um componente TEdit
no formulário, nomeando-o como edtMensagem
. Em seguida, adicione também um botão e altere a propriedade Caption
para “Gravar Arquivo INI”. A função deste botão será gravar a mensagem contida na TEdit
dentro do arquivo INI que será criado.
O próximo passo é criar uma variável do tipo TIniFile
, e então instanciá-la com o caminho e nome do arquivo INI. Para efeitos de demonstração, criaremos o arquivo INI dentro do C:\
, mas esta não é uma regra. O arquivo pode ser armazenado em qualquer diretório no computador.
Mãos à obra: dê dois cliques no botão e insira o seguinte código:
1 2 3 4 5 6 7 8 |
var ArquivoINI: TIniFile; begin ArquivoINI := TIniFile.Create('C:\Configuracao.ini'); ArquivoINI.WriteString('Exemplo', 'Mensagem', edtMensagem.Text); ArquivoINI.Free; ShowMessage('Mensagem armazenada com sucesso!'); end; |
No exemplo acima, após a variável ter sido declarada e instanciada, já podemos manipular o conteúdo do arquivo INI. Para gravar o conteúdo, utilizei o método WriteString
, responsável por armazenar o dado na seção e propriedade informados.
O método WriteString
exige 3 parâmetros de entrada: o primeiro é nome da seção, o segundo é o nome da propriedade, e o terceiro, o valor a ser armazenado. Veja que forneci o nome “Exemplo” para a seção e o nome “Mensagem” para a propriedade. Estes nomes serão importantes posteriormente na leitura do arquivo.
Por fim, utilizamos o método Free
para liberar a referência do arquivo da memória, já que terminamos de manipulá-lo. Execute a aplicação, clique no botão e depois verifique que o arquivo “Configuracao.ini” foi criado no C:\
 do computador. Se você abrir este arquivo, verá que ele estará na seguinte estrutura:
1 2 |
[Exemplo] Mensagem=Mensagem da TEdit |
Pronto, gravamos a informação no arquivo INI!
Lendo arquivos INI
Porém, de nada adianta gravar uma informação se não sabemos como acessá-la, não é? Bem, volte à aplicação e adicione um novo botão, alterando a propriedade Caption
apara “Ler Arquivo INI”. O código deste botão é bem semelhante ao código acima, exceto pelo método de acesso ao conteúdo:
1 2 3 4 5 6 7 8 9 |
var ArquivoINI: TIniFile; Mensagem : string; begin ArquivoINI := TIniFile.Create('C:\Configuracao.ini'); Mensagem := ArquivoINI.ReadString('Exemplo', 'Mensagem', 'Erro ao ler o valor'); ArquivoINI.Free; ShowMessage('Mensagem armazenada no arquivo INI: ' + #13 + Mensagem); end; |
O método ReadString
tem a função de ler o dado da seção e propriedade informados por meio de três parâmetros de entrada: o primeiro é o nome da seção, o segundo é nome da propriedade, e o terceiro é o valor retornado caso ocorra algum erro na leitura da propriedade. Nesta rotina, a mensagem contida no arquivo INI foi atribuÃda a uma variável do tipo string, e em seguida exibida ao usuário através do ShowMessage
.
Gravando outros tipos de valores
É importante ressaltar que para o exemplo acima utilizei somente os métodos para gravação e leitura de valores do tipo string. Para manipular outros tipos de dados, basta utilizar as respectivas funções disponibilizadas pelo Delphi, como WriteInteger
e ReadInteger
para número inteiro, WriteFloat
e ReadFloat
para números reais ou WriteDate
e ReadDate
para datas. Nada impede também que vários dados sejam gravados ou lidos em uma única rotina, como o exemplo abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Gravação ArquivoINI := TIniFile.Create('C:\Configuracao.ini'); ArquivoINI.WriteString('Valores', 'Mensagem', 'Este é um exemplo'); ArquivoINI.WriteInteger('Valores', 'Contador', 5); ArquivoINI.WriteFloat('Valores', 'Preço', 12.56); ArquivoINI.WriteDate('Valores', 'Backup', '20/08/2012'); // Leitura Edit.Text := ArquivoINI.ReadString('Informacoes', 'Usuario', ''); RadioGroup.ItemIndex := ArquivoINI.ReadInteger('Informacoes', 'Opcao', 0); // Liberação da memória ArquivoINI.Free; |
Simples, não? Utilizar arquivos INI certamente garante uma maior flexibilidade nas configurações da aplicação, portanto, procure utilizá-los sempre quando possÃvel. O projeto de exemplo foi desenvolvido em Delphi XE e pode ser baixado neste link.
Troubleshooting
Ops, ocorreu algum erro ao manipular o arquivo INI? Veja se uma das respostas abaixo pode lhe ajudar:
1) Ao compilar o projeto, recebo a mensagem: E2003 Undeclared identifier: ‘TIniFile’.
Declare a referência IniFiles na seção uses do formulário, logo no inÃcio do arquivo de código-fonte.
2) Ao compilar o projeto, recebo a mensagem: E2035 Not enough actual parameters.
Um dos métodos não está recebendo a quantidade de parâmetros necessária. O método WriteString
, por exemplo, exige três parâmetros de entrada que devem ser obrigatoriamente informados. Se houver dúvidas na quantidade de parâmetros exigida, pressione Ctrl + Shift + C
para exibir a lista de parâmetros da função.
3) Declarei e instanciei a variável, mas o arquivo não é criado.
Verifique se a pasta informada no código-fonte realmente existe no computador, e se os nomes estão corretos. Além disso, existem algumas pastas que são protegidas pelo sistema. Se o usuário não possuir permissão de acesso à pasta, o arquivo não será criado por questões de segurança.
4) Recebo uma exceção de Access Violation ao ler ou gravar o arquivo.
Verifique se ele está sendo criado corretamente através do método Create
. Se você tentar ler ou gravar dados antes de criar o arquivo, o Delphi retornará um erro de acesso. Lembre-se também de liberar a variável da memória após terminar de trabalhar com o arquivo INI.
5) Os valores são gravados, mas não são lidos corretamente.
Este problema exige atenção nos parâmetros dos métodos. Confira se o nome do arquivo gravado é o mesmo nome que está sendo utilizado na rotina de leitura. E o mais importante: confira os nomes das seções e propriedades. Se o Delphi não encontrar a seção ou propriedade informada, o retorno será nulo. Procure também utilizar os métodos para o mesmo tipo de dado armazenado, ou seja, se gravar um valor com o método WriteString
, leia-o com ReadString
, e assim por diante.
Em caso de dúvidas, erros ou sugestões, deixe um comentário!
Um abraço a todos!
Quero parabenizá-lo pelos ótimos artigos que você tem publicado, pois, percebo que o seu diferencial em relação aos outros sites que postam artigos sobre Delphi esta na didática com detalhes. continue assim, sempre detalhista, ajudando os programadores iniciantes a conhecer e a pegar o gosto pela Ferramenta Delphi.
Olá, Ademario!
Muito obrigado pelo comentário! Espero continuar sempre compartilhando conhecimento com outros Delphianos!
Abraço!
Realmente a forma como passa os detalhes vemos o seu diferencial parabens!
André você esta de parabens, o post tem uma didática maravilhosa rica em detalhes e de facio compressão.
Parabens novamente pelo otimo trabalho.
Otima explicação, parabéns.
Já utilizo esses tipo de arquivo há algum tempo, mas estou tendo problemas para criptografa-lo para que o usuário quando abrir não possa visualiza-lo e modifica-lo.
Poderia sugerir uma rotina de criptografia do arquivo ini para ler e cria-lo.
obrigado
Olá, Hideki. Infelizmente não há uma forma consistente de criptografar arquivos INI, ainda mais que, caso fosse possÃvel, você teria alguns problemas de ler as seções e as chaves do arquivo no Delphi. Uma alternativa é usar uma função de criptografia para gravar os valores no arquivo INI, como por exemplo, ao invés de gravar “Delphi”, a função gravaria “5&R0@”.
Olá!
Como eu faria para poder ler um arquivo ini em linhas… no caso preciso colocar nomes de schemas do banco de dados, um em cada linha de um memo, gravo estes dados em um .ini criptografado e leio em runtime para setar o schema no banco de dados e fazer minhas buscas. Como posso fazer isto? Obrigada!
Olá, PatrÃcia. Pra ficar mais fácil, vou entrar em contato com você por e-mail pra te ajudar, ok? Obrigado pela visita!
Ok. Agradeço teu retorno!
Olá, como fária pra que o arquivo ini se relacionasse com o banco de dados do meu interbase, no caso as relações já estão tudo feitas(cadastrar,apagar,atualizar)? Preciso fazer isso, pro meu software funcionar em outro computadores além do meu. Se souber me ajudar agradeceria, abraço.
Olá, Ricardo. Vou lhe enviar o código por e-mail, ok?
Obrigado por deixar o comentário!
Olá, novamente. Ajudou assim, mas continuo com uma dúvida, eu uso o Ibconsole, e para usar o banco que ele cria eu tenho de usar um usuario e um password, que são SYSDBA e masterkey respectivamente (não estou em casa, e aqui não posso testar, por isso a pergunta). Esses dois seriam a secao e a chavebancodedados ou não? Desculpa se for alguma pergunta idiota, mas sou um pouco novo no Delphi, sei umas coisas mas esse não, e gosto de aprender para eu conseguir desenvolver futuros projetos com um bom funcionamento, desculpa o incomodo, abraço e obrigado.
Olá, Ricardo. Imagina rapaz, não existem perguntas idiotas. Todo mundo está aprendendo no dia-a-dia!
Ricardo, no código que lhe enviei há uma seção e uma chave somente para efeito de exemplo. Você pode gravar uma seção com várias chaves para armazenar quantos valores forem necessários:
[Secao]
UsuarioBD=SYSDBA
SenhaBD=masterkey
CaminhoBD=C:\Aplicativo\Banco.gdb
Vou lhe enviar um e-mail com mais detalhes.
Olá Andre, estou tentando configurar uma conexão com meu banco de dados utilizando arquivo de extensão .ini, a configuração local funciona perfeitamente porém estou tendo problemas quando tento me conectar em rede a um servidor, ja tentei mapear a unidade e colocar o caminho mapeado e também pelo endereço de ip mas não obtive exito, o que pode ser?
Olá, Gustavo. Vou entrar em contato com você por e-mail para tentarmos identificar o problema, ok? Abraço!
Bom dia, André! Primeiramente, desculpe por ‘desenterrar’ seu post, mas estou com uma dúvida. Como faço para ler mais de um valor na seção? Por exemplo:
[Seção1]
propriedade1 = valor1
propriedade2 = valor2
propriedade3 = valor3
Como faço para retornar somente o valor1, valor2 e valor3?
Obrigado por sua atenção. Abraço!
Olá, Rafael! Não se preocupe em comentar nos artigos antigos. Os comentários são importantes e complementam as informações do artigo.
Bem, a respeito da sua dúvida, os arquivos INI são gravados em uma estrutura onde cada chave pode ter somente um único valor, portanto, para ler cada valor, é preciso acessar a sua chave correspondente.
Uma alternativa para este caso é armazenar o valor em apenas uma chave com algum tipo de delimitador, como a vÃrgula, o pipe ( | ) ou barras. Por exemplo:
propriedade=valor1|valor2|valor3
Dessa forma, no Delphi, basta ler estes delimitadores e considerar cada palavra separada como uma linha.
Quero parabenizá-lo pelo ótimo site! Todos os artigos e publicações são claras, objetivas e tem sido de muita ajuda.
Olá, Sávio! Muito obrigado pelo feedback. Fico contente que os artigos lhe ajduaram! Abraço!
Oi alguem poderia me ajuda criar um .ini para banco dados
se puder add no skype
Olá, Ismael. Vou entrar em contato com você por e-mail, ok? Abraço!
Ola amigo Andre Luis, primeiramente muito obrigado pelo otimo tutorial, mas estou com uma duvida..
eu criei um arquivo config.ini com 2 seções uma [LIGAR] e outra [DESLIGAR] na primeira seçao eu coloquei :
[LIGAR]
LOGIN = \\Sem valores estipulado usuario estipula
LOGIN_Dir= \\Sem local estipulado usuario estipula
LOGIN_Delay=\\Sem tempo para execução usuario estipula o intervalo de tempo de uma execuçao para outra
E na segunda seção eu coloquei:
[DESLIGAR]
LOGIN = \\ Deixei em branco para que o usuario estipule o executavel que ele quer encerrar, como os valores acima tambem ficaram em branco para que o usuaria possa estipular e a interface leia e abra co arquivo no diretorio que ele esta armazenado, mas nao estou conseguindo criar o codigo em delphi com um botão para fazer esta açao funcionar para ligar e ler todas as informaçoes que o usuario colocou no config.ini e executar o arquivos .exe… por favor poderia me ajudar com isso..
obrigado.
Olá, Arthur! Vou entrar em contato com você por e-mail pedindo mais detalhes, ok?
Abraço!
Caro amigo Andre Luis muito obrigado por me responder por email. seu codigo resolveu meu problema.. obrigado
Amigo no meu caso preciso gravar 3 seção, cada seção vai ser gravado vários valores, no meu caso ele esta gravando, mas toda vez que entro com um dado novo ele sobrescreve o que já existe. eu teria que gravar uns 30 valores em cada seção, para fazer a leitura depois.
Olá, Maycom! Isso mesmo, a cada vez que você escrever um valor em uma chave, o valor antigo será sobrescrito. Se você pretende gravar vários valores em uma única seção, então terá que especificar nomes diferentes para as chaves.
Boa noite meu caro! Suas explicações estão bastante claras, parabéns! Nós curiosos em programação ficamos muito gratos, pois nossos “programinhas de fundo de quintal” precisam funcionar e nós não sabemos como fazer isso, mas existem profissionais competentes como você que não se esquivam de ajudar a nós que apenas brincamos com programação! rsrsrs…
Eu estou pesquisando sobre INI para um programinha básico que estou fazendo, e já consegui gerar e gravar dados em um INI com sucesso.
Esses dados, nada mais são do que o caminho de uma (ou talvez outras futuramente)planilha que desejo que seja aberta quando eu clicar no menu de meu pequeno programa onde consta o nome desta planilha.
Precisei fazer por meio de INI, por que algumas vezes outros usuários ficam movendo ou trocando o nome desta planilha, e eu obviamente acho mais conveniente poder colocar em um INI através da opção configurações de meu programa, o caminho desta planilha do que ficar mexendo no fonte.
Ok, isso eu já consegui…
Mas, eu gostaria que quando eu clicasse no menu onde está o nome desta planilha, o programa acessasse este caminho que está gravado no INI, e em seguida abrisse a planilha.
Achei que daria para fazer por Shell execute ou por Winexec, mas obviamente não funciona, e eu não sei MESMO como fazer, já que tenho menos de um mês de aprendizado em Delphi…
Será que há como fazer isso??
Olá, Jadilson! Em primeiro lugar, devo parabenizá-lo pela clareza na sua escrita! Você conseguiu se expressar muito bem no comentário e me deixou sem sombra de dúvidas.
Bom, Jadilson, já que é uma questão mais ampla, vou lhe enviar um e-mail com uma possÃvel solução, ok?
Abraço!
André, bom dia!
Achei que seria interessante deixar um comentário
a respeito de minha pergunta, também aqui no blog, já que agora estou visitando com frequencia.
Agradeço novamente por sua ajuda!
Como eu já lhe disse, o código que você me enviou
é simples para você que tem conhecimento e para mim seria algo bem mais difÃcil(e olha que procurei pela internet para ver se achava algo que me ajudasse, e se há, não encontrei!)
Felizmente você não se esquiva de ajudar, Muito obrigado!
Que Deus o abençoe e à sua famÃlia!
Olá, Jadilson! Novamente lhe agradeço pelo apoio e pelo comentário no blog!
Fiquei contente ao saber que a minha ajuda foi útil para solucionar a sua dúvida. Espero que continue visitando o blog.
Um grande abraço!
Parabéns pelo artigo. Gosto de programar em delphi pra desestressar e agora entendi como estruturar um arquivo de configuração por meio de um arquivo INI. Já tentei em outras explicações mas a sua é super simples e direta. Valeu cara!
Olá, Vandeilson! É gratificante saber que o artigo lhe ajudou!
Obrigado pelo feedback! Abraço!
tenho um software que usa um arquivo INI , o qual controla quantidade de terminal para acessar o programa juntamente com a licença, gostaria de saber se tem como editar o arquivo para alterar a quantidade de terminal para acessar o programa e como faço isso ???
Olá, Lucio!
Arquivos INI podem ser editados pelo bloco de notas, já que são arquivos de texto simples.
Para isso, clique com o botão direito no arquivo e selecione “Abrir com” > “Bloco de notas”.
Abraço!
Vlw André, me ajudou bastante, gostei da forma como fez o arquivo muito bem detalhado, parabens.
Olá, EvaldoRDS!
Muito obrigado pela visita e também pelo feedback!
Abraço!
Muito bom seus artigos. São de grande utilidade e de fácil aprendizagem. São artigos de fácil entendimento e que prendem a nossa atenção. Parabéns.
Olá, Renan, tudo bem?
Muito obrigado pelo feedback e pela motivação!
Espero que continue visitando o blog.
Abraço!
Olá André, primeiramente parabéns pelo ótimo conteúdo disponibilizado.
Vai minha dúvida: Como ler determinada propriedade quando seus dados possuem quebra de linha, ou seja, ocupa mais de uma linha?
Explico: Salvar dados contidos em um componente TMemo(com vários “enters”) e depois recuperá-lo novamente nesse TMemo.
Utilizando o código abaixo, ele só me retorna a primeira linha da propriedade.
memo.lines.text := ArquivoINI.ReadString(‘Exemplo’, ‘Mensagem’, ”);
Tem como fazer utilizando o .ini ou há outra opção melhor.(Apesar que todo o aplicativo já está funcional e mudar isso seria trabalhoso demais).
Olá, Castilhos, tudo bem?
O FAQ 1 do blog traz uma questão de um leitor que já teve a mesma dúvida. Confira:
https://www.andrecelestino.com/perguntas-respostas-comentarios-blog-faq/
Abraço!
Gostei muito da sua explicação sobre arquivos ini. Só que estou tentando executar programas portáteis por meio de um apricativo que eu criei, gostaria de saber se da para fazer isso por meio de arquivos ini.
Peço, por favor, que não mande exemplo com imagem pois sou cego. Rsrsr Parabéns pela página . Já adicionei aos meus favoritos
Olá, Edilberto!
Muito obrigado pelo seu feedback sobre o artigo! Isso é muito importante para que eu continue o meu trabalho!
Sim, Edilberto, você pode programar os seus aplicativos portáteis para ler as configurações de um arquivo INI. Dessa forma, você poderá executá-los em qualquer computador. Para simplificar essa leitura, procure colocar o arquivo INI na mesma pasta do executável. Isso possibilita a leitura independente do diretório em que o programa está!
Grande abraço!
Excelente prática de ensinar, muito obrigado.
Obrigado, Jeová!
Abração!
André tou com um problemao aqui com arquivos ini…
tenho um combobox q era para gravar o texto:
DeptoAgenda=Suporte – São Paulo (Esse Suporte – São Paulo o ã sai com um caractere estranho)
essa gravação está sendo feita com :
cxGrid1DBTableView1.StoreToIniFile(Ini.FileNameFull, False, [], ”);
Não sei dizer se isso está afetando a gravação padrao utilizada ai no artigo..tipo colocando outro tipo de formatação UTF-8 seila… o normal ai que usamos no artigo é formatação tipo ANSI ?
Opa, olá, MaurÃcio!
Como não tenho familiaridade com o componente TcxGrid, vou entrar em contato com você para tentarmos achar uma solução juntos.
Abraço!
Boa tarde André !
Parabéns pelas dicas sempre boas…
Sou novato em delphi , surgiu uma dúvida como gero isso: {$R *.RES}?
Obrigado!
Boa tarde, Mailson, tudo bem?
Obrigado pelo feedback.
A diretiva {$R *.RES} é gerada automaticamente no arquivo DPR ao criar um novo projeto. Para visualizá-lo, acesse o menu Project > View Source.
Abraço!
Muito obrigado!
Sempre estou aprendendo por aqui.
Bom dia, André.
Seria muito interessante se você explicasse em um artigo como trabalhar com DLL no Delphi. Estou pesquisando sobre isso e acho legal a forma como você explica as coisas, mas ainda não tem nada sobre DLL com Delphi.
Olá, Tiago, boa tarde!
Anotado! Obrigado pela sugestão.
Em breve elaboro um artigo abordando as diferentes formas de carregar DLLs no Delphi.
Grande abraço!
Boa tarde !!!
André, pelo arquivo INI consigo fazer a conexão ao meu banco de dados em Access? Estou usando ADOQuery e o grande problema é que os usuários do sistema gostam de instalar o programa em um outro diretório.
Olá, Mailson, boa noite!
Infelizmente não tive a oportunidade de trabalhar com o banco de dados Access, mas, mesmo assim, imagino que a configuração de rede não seja tão diferente dos outros bancos. Acredito que você terá que ler o valor no arquivo INI e atribuÃ-lo à propriedade ConnectionString do componente TADOConnection.
Recomendo também a leitura do artigo abaixo, que traz um exemplo de configuração de uma connection string em rede:
Conexão Remota com ADOConnection
Abraço!
🙂
Olá, estou com dificuldade em como gravar Data, Hora de inicio e fim do sistema + o tempo de execução do sistema em arquivo INI. Como posso fazer isso?
Obrigado!
Olá, Ronaldo!
Para gravar datas em arquivos INI, basta utilizar a função WriteDate, como no exemplo abaixo:
Do mesmo modo, para gravar horas, utilize a função WriteTime.
Porém, para gravar o tempo de execução do sistema, é preciso primeiramente realizar um cálculo antes de gravar o valor no arquivo INI. Para isso, ao iniciar o sistema, armazene o valor da função
Now
em uma variável. Ao encerrá-lo, armazene novamente o valor deNow
em outra variável. Em seguida, subtraia essas duas variáveis para obter o tempo de execução do sistema.Abraço!
Olá ! Boa matéria, parabéns !
Tenho uma questão, quando gravo uma chave maior que 255 caracteres, e tento ler, o método ReadString só me retorna os 1os 255 caracteres, tem alguma solução para isso ? Minha chave tem 344 caracteres, o método WriteString consegue gravar sem problemas.
Olá, Samuel, tudo bem?
Fiquei curioso com essa situação e codifiquei um pequeno teste na versão Tokyo. Nesse teste, o método
ReadString
conseguiu ler 275 caracteres, correspondendo ao texto completo que está no arquivo INI.Você poderia enviar a versão do Delphi que você está utilizando e o código da rotina de leitura para o [email protected]?
Abraço!
André, bom dia! Tudo bem?
Estou com uma dúvida. Quando eu uso o create ele não cria novamente o arquivo, se ele já existir? O problema que estou tendo é que crio o arquivo, faço a escrita. Depois de um tempo, quero escrever novamente, porem ele está excluindo os dados que já inseri. Como proceder nesse caso? Ou seja, para deixar salvo as informações, e depois eu conseguir escrever na próxima linha, na qual já existe informações.
Obrigado e parabéns pelo artigo. Muito me auxiliou.
Olá, Marcelo, boa tarde!
Em primeiro lugar, obrigado pelo feedback.
Marcelo, o objetivo do arquivo INI é armazenar valores em seções e chaves para serem recuperados posteriormente. Portanto, uma nova escrita em um arquivo INI é semelhante à edição de um registro em uma tabela: os dados anteriores são descartados e os novos dados são gravados.
Sendo assim, considere um arquivo INI com essas informações:
Ao executarmos o método abaixo…
… o valor “Exemplo” será sobrescrito por “Teste”.
Caso a sua intenção seja armazenar gradativamente novos dados no arquivo, sem sobrescrever o conteúdo existente, talvez seja mais viável gravar estes dados em linhas de um arquivo TXT:
Neste caso, outros métodos são utilizados, como
LoadFromFile
,SaveToFile
e a classeTStringList
.Abraço!
Bom dia Andre !
O método está correto, eu é que havia cometido um erro na minha rotina, por isso o retorno estava truncado.
Muito obrigado pelo retorno…
Abraço !
Ok, Samuel, sem problemas!
Abração!
Bom dia André !
Excelente material, realmente me ajudou muito e acredito a todos que chegaram aqui. Mas ainda tenho uma dúvida, acredito que outros ainda não passaram por isso pois não encontrei nos comentários. Como seria se o retorno da tag fosse uma string com mais de uma linha, com quebra de linha por exemplo?
EX:
Desde já agradeço a atenção.
Olá, Alexandre!
A estrutura de um arquivo INI não permite o armazenamento de textos com quebras de linha. Na verdade, o arquivo ficaria dessa forma:
Porém, ao ler a chave “Teste”, o texto retornado será apenas “Linha1”.
Uma alternativa para este caso é gravar valores separados por vÃrgula em uma única chave:
Deste modo, ao atribuir este texto à propriedade CommaText de um objeto da classe TStringList, os valores serão separados em posições, ou seja, quebrados por linha.
Abraço!
Muito obrigado André,
Consegui resolver aqui com a sua ajuda.
Agradeço a agilidade na resposta e vou continuar acompanhando seus posts, realmente ajudam muito.
Abraço e até mais.
Eu que agradeço pelo retorno, Alexandre!
Continue acompanhando o blog 😉
Abraço!
Como criptografar arquivo INI??
Olá, Victor.
Você pode criar suas próprias regras de criptografia (por exemplo, substituindo caracteres ou utilizando base64), ou utilizar rotinas já existentes compartilhadas em alguns fóruns, como essa do StackOverflow:
https://stackoverflow.com/questions/14411975/simple-code-to-encrypt-an-ini-file-string-using-a-password
Há também o DCPCrypt, uma biblioteca aberta disponÃvel no BitBucket:
https://bitbucket.org/wpostma/dcpcrypt2010/src/default/
Abraço!
Olá,
Qual seria a forma mais “adequada” para não permitir que o arquivo não seja alterado “por fora” da aplicação que utiliza e edita o arquivo ini ?
Olá, Fábio!
Se os dados do arquivo INI não podem ser alterados fora da aplicação, eu sugiro que você use outra abordagem para armazenar os parâmetros, como, por exemplo, uma tabela no banco de dados. O propósito do arquivo INI é armazenar apenas configurações básicas, que não sejam sigilosos e não comprometam o funcionamento do sistema.
Outra alternativa é criptografar o arquivo INI, mas, neste caso, você terá que implementar uma rotina de criptografia.
Abraço!
Boas uma ajuda como converter ArquivoINI := TIniFile.Create(‘C:\Configuracao.ini’);
para uma String
Converter o ArquivoINI para uma String;
Olá, Marco, tudo bem?
Você não pode converter um objeto
TIniFile
para string, pois são de tipos diferentes.Se você precisa ler o conteúdo do arquivo INI, então basta utilizar o método
ReadString
:Abraço!
Boa tarde André!
è possÃvel separar as sessões com uma linha em branco no final de cada sessão?
Para não ficar uma sessão colada uma na outra.
Questão de estética mesmo no arquivo INI.
Abraços
Olá, Joca, boa tarde!
Como a classe TIniFile trabalha somente com a estrutura do arquivo, não é possÃvel “pular” linhas entre seções.
Para isso, você teria que manipular o arquivo como um texto, trabalhando, por exemplo, com a classe
TStringList
ouTextFile
.Abraço!
Boa noite André!
Tudo bem com você?
Por gentileza
Como faço para gravar e ler a cor do dbgrid pelo arquivo INI?
Olá, Mailson, como vai?
Você pode utilizar a função ColorToString para converter a cor em uma string e então gravá-la no arquivo INI.
Para carregar basta fazer o inverso com a função StringToColor.
Abraço!
André boa noite, tenho uma dúvida. Criei um arquivo .ini para ser lido e editado na atualização das versões do meu sistema. Estou tendo um problema que o firewall do Windows não está permitindo editar o arquivo .ini para atualizar o número da última versão lida. Como posso fazer para deixar esse arquivo .ini sempre editável pelo Delphi?
Olá, Wilton, tudo bem?
Bom, a princÃpio, se você consegue editar o arquivo manualmente (no Notepad, por exemplo), então pelo Delphi também teria que dar certo.
Experimente iniciar a sua aplicação como administrador. Se mesmo assim não funcionar, me envie um e-mail ([email protected]) para conversamos melhor.
Abraço!
Rapaz andré, você é o cara. O único problema era a execução do aplicativo como Administrador. Funcionou perfeitamente. Muitissimo obrigado. Tenho uma outra dúvida relacionada a um combobox, mas vou te enviar um e-mail. Obrigado!
Que bom que funcionou, Wilton!
Abração!
boa tarde, uma duvida consigo fazer com que um form so seja visivel no meu projeto se ele estiver marcando dentro do arquivo ini, queria por uma parametro no arquivo ini e so for 1 ele o form fica visivel, se for 0 o form fica oculto no projeto e possivel fazer isso?
Olá, Thiago.
Sim, é possÃvel. Basta trabalhar com a função
ReadInteger
, que permite a leitura de valores inteiros do arquivo INI.Conforme o valor que for lido, você exibe ou esconde o formulário.
Abraço!
Muito obrigado pelo post. Uma pergunta: é possÃvel carregar um arquivo Ini direto na memória (pelo TMemoryStream, por exemplo) em vez de salva-lo em disco? Já que o TIniFile.Create exige uma String. Mais uma vez, obrigado.
Olá, Renato, tudo bem?
Boa pergunta. Até abri a documentação do Delphi para verificar e, pelo que pude notar, há apenas um construtor da classe TIniFile, no qual aceita uma string como parâmetro. Não há outros construtores com parâmetros diferentes.
Portanto, acredito que essa é a única forma de trabalhar com essa classe.
Abraço!
Bom dia, depois de um final de semana de pesquisas, consegui chegar ao resultado 😀
Segue:
vStream:=TMemoryStream.Create;
//Passa o arquivo INI para o MemoryStream (no meu caso, o INI veio de um FTP: Get('Arquivo.ini', vStream, False);
vStringStream:=TStringStream.Create;
vStringStream.LoadFromStream(vStream);
vString:=TStringList.Create;
vString.LoadFromStream(vStringStream);
vMemIni:=TMemIniFile.Create('');
vMemIni.SetStrings(vString);
A partir do vMemIni, faz-se a leitura dos campos normalmente (ReadString, ReadSection, etc);
Abraço!
Opa, legal, Renato. Obrigado pela contribuição!
Eu acho que o Delphi poderia disponibilizar esse mecanismo de carregar a partir de streams de forma nativa. Já pouparia o seu final de semana, rsrs.
Abraço!
Salve. Bom artigo.
Aoooooo, Marcos! Quanto tempo!
Obrigado!
Parabéns pelo artigo André, mas como eu consigo utilizar o DCPcrypt2, eu estava usando a versão do delphi 2007, mas estou tentando migrar para o alexandria e não estou conseguindo… você teria algum exemplo?
Olá, Márcio.
Infelizmente tenho pouca experiência com DCPCrypt2. Além disso, não tenho conhecimento se essa biblioteca tem sido atualizada para as últimas versões do Delphi.
De qualquer forma, encontrei o tópico abaixo no Stack Overflow que orienta a instalação do DCPCrypt2 no Delphi 10.4 a partir de um pacote antigo:
https://stackoverflow.com/questions/68796512/installing-and-using-dcpcrypt2-in-delphi-10-4
Espero que ajude.
Abraço!
Boa noite pessoal.
Algumas dicas ao trabalhar com arquivos *.ini:
1 – Ao gravar/regravar o arquivo, você grava/regrava o arquivo inteiro. Grave tudo de uma só vez.
1.a – Crie uma function que grava tudo que for necessário, de uma só vez, e testa se deu certo a gravação, retornando falso ou verdadeiro para essa situação, e chame essa função quando precisar gravar algo.
1.b – O mesmo para a leitura do arquivo *.ini;
Exemplo:
Private
{ Private declarations }
Function LeIni(IniArq: String): Boolean;
Function GravaIni(IniArq: String): Boolean;
implementation
Function Tf_Main.GravaIni(IniArq: String): Boolean;
Var
Ini: TIniFile; // Declaração do Arquivo INI
Begin
Result := False; // Garante que, se houver erro, retorno será de erro de gravação
Ini := TIniFile.Create(IniArq); // Tenta abrir o arquivo. Se o arquivo não existe, ele cria.
If (IOResult 0) Then // Caso não consiga abrir ou criar o arquivo
// Apresenta mensagem de erro
Application.MessageBox('Erro na abertura do Arquivo de Configurações!!!', 'Aviso do Sistema', MB_OK)
Else // Caso consiga abrir ou criar o arquivo
Begin
// Grava as informações no arquivo
Ini.WriteString('PRINCIPAL', 'Prog_Lang', Prog_Lang); // Grava, na Seção PRINCIPAL, no Campo Prog_Lang, o valor da variável/campo de tabela Prog_Lang
Ini.WriteString('PRINCIPAL', 'Diretorio', Diretorio); // Grava, na Seção PRINCIPAL, no Campo Diretorio, o valor da variável/campo de tabela Diretorio
Ini.WriteString('CONFIGURACAO, 'EventLog', EventLog); // Grava, na Seção CONFIGURACAO, no Campo EventLog, o valor da variável/campo de tabela EventLog
Ini.WriteString('VENDA', 'Prod_ID', Prod_ID); // Grava, na Seção VENDA, no Campo Prod_ID, o valor da variável/campo de tabela Prod_ID
Ini.WriteInteger('VENDA', 'Prod_Quant', Prod_Quant); // Grava, na Seção VENDA, no Campo Prod_Quant, o valor da variável/campo de tabela Prod_Quant
Ini.WriteFloat('VENDA', 'Prod_Valor', Prod_Valor); // Grava, na Seção VENDA, no Campo Prod_Valor, o valor da variável/campo de tabela Prod_Valor
Ini.WriteDate('VENDA, 'Venda_Data', Venda_Data); // Grava, na Seção VENDA, no Campo Venda_Data, o valor da variável/campo de tabela Venda_Data
Ini.Free; //libera o Arquivo *.ini
Result := True; // Se chegou até aqui, a gravação foi efetuada corretamente
End ;
End ; // Retorna à rotina que chamou a função GravaIni
Function Tf_Main.LeIni(IniArq: String): Boolean;
Var
Ini: TIniFile; // Declaração do Arquivo INI
Begin
Result := False; // Retorno como erro de letura
If FileExists(IniArq) Then // Verifica se o arquivo Aplicativo.INI existe
Begin // Se o arquivo Aplicativo.INI existir
Ini := TIniFile.Create(IniArq); // tenta abrir o arquivo
If (IOResult 0) Then // Caso não consiga abrir o arquivo
Application.MessageBox('Erro na abertura do arquivo !!!', 'Aviso do Sistema', MB_OK) // Apresenta mensagem de erro
// Detalhe aqui: Como estou dentro de um If/Else/End, não uso o ponto e vÃrgula no final da linha, antes do Else, senão o Pascal interpretará que meu If terminou.
Else // Caso consiga abrir o arquivo
Begin
// Lê as informações do arquivo
Prog_Lang := Ini.ReadString('PRINCIPAL', 'Prog_Lang', 'Pt_Br'); // Lê os dados do Campo Prog_Lang e salva na variável/Campo de tabela Prog_Lang. Se não encontrar o Campo, no arquivo *.INI, usa o valor 'Pt_Br' como padrão.
Diretorio := Ini.ReadString('PRINCIPAL', 'Diretorio', 'C:\Teste\'); // Igual acima
EventLog := Ini.ReadString(''CONFIGURACAO, 'EventLog', 'Venda'); // Igual acima
Prod_ID := Ini.ReadString('VENDA', 'Prod_ID', '1'); // Igual acima. Detalhe é que, aqui, passo o caractere 1, não o valor 1
Prod_Quant := Ini.ReadInteger('VENDA, 'Prod_Quant', 1); // Igual acima. Detalhe é que, aqui, passo o valor 1, não o caractere 1
Prod_Valor := Ini.ReadFloat('VENDA', 'Prod_Valor', 1.06); // Igual acima. O ReadFloat aceita um valor inteiro mas, um ReadInteger não aceita um valor de ponto flutuante.
Venda_Data := Ini.ReadDate('VENDA, 'Venda_Data', Now); // Igual acima.
Ini.Free; // Libera o arquivo *.INI
Result := True; // Se chegou até aqui, a leitura foi efetuada com sucesso
End;
End;
End; // Retorna à rotina que chamou a Função LeIni
2 – Hoje, as rotinas criadas funcionam tanto no Delphi como no Lazarus, não importa onde as tenha criado. O importante é o código estar correto.
3 – Caso estejam criando um aplicativo pra uso próprio, sem problemas. Caso estejam criando um aplicativo pra outros usarem, não importa o porque ou quem, pensem que seus usuários PODEM ser QUASE negligentes (já vi muitos, rsrs). Criem seus aplicativos o mais mastigado possÃvel, pois você não sabe quem irá utilizá-los. Quem tiver tempo, coloque um sistema de Ajuda (HELP) interno, bem explicadinho.
Olá, Luis.
Primeiramente, desculpe pela demora.
Obrigado pela contribuição! Suas dicas foram bem observadas.
Como esse artigo já está beeem antigo (quase 12 anos!), pretendo refazê-lo, mas com melhores práticas. Hoje o Delphi tem bibliotecas aprimoradas para trabalhar com arquivos de texto.
Abraço!