nunopicado Posted March 26, 2012 at 05:55 PM Report #445754 Posted March 26, 2012 at 05:55 PM O Pascal sempre foi uma linguagem de trato fácil, e trabalhar com ficheiros não é excepção. Portanto, foi com naturalidade que essa simplicidade foi transmitida ao Delphi, que manteve a mesma forma de abrir ficheiros de texto, atribuindo o ficheiro a uma variável, que depois seria lida sequencialmente para uma qualquer string, e com isso, teríamos o conteúdo do ficheiro. No entanto, esta natureza sequencial, obrigatoriamente usada nos tempos em que a memória RAM era limitada ao mínimo essencial, tornou-se algo obsoleta nos dias que correm, em que virtualmente todos os ficheiros de texto cabem perfeitamente, e por inteiro, na memória RAM dos PC's actuais, o que facilita o acesso em simultâneo a todo o conteúdo do ficheiro. Com isto, já não estamos limitados ao acesso sequencial de outrora, podendo literalmente "saltar" entre as linhas do ficheiro a nosso bel-prazer, ler umas, gravar outras, inserir outras ainda, pesquisar, etc. E claro, como não podia deixar de ser, em Delphi, isso é uma operação facílima. TStrings - A classe A classe TStrings tem por base um array dinâmico de Strings. Em termos simplistas, poderíamos assim declarar: type TStrings:Array of String; No entanto, esta classe tem mais do que um simples array. Trás consigo uma série de propriedades e métodos que facilitam o seu uso. Entre eles, os muito úteis LoadFromFile e SaveToFile, carregam e gravam, respectivamente, os dados de e para um ficheiro de texto. Assim, com um só comando, podemos ler todo o conteudo de um ficheiro de texto para a memória, onde poderá ser trabalhado e acedido directamente pelo número de linha (índice do array), e por fim, com uma instrução gravar outra vez num ficheiro. A classe TStrings não é geralmente usada drectamente, mas está presente em diversos dos mais conhecidos componentes de texto, como os TComboBox, TListBox, TMemo, TRichEdit, etc. através das propriedades Items no caso dos dois primeiros e Lines no caso dos últimos. Na prática: Cenário 1: Queremos carregar um ficheiro de texto para o mostrar ao nosso utilizador, com a possibilidade de edição, ao estilo de um bloco de notas, por exemplo: - Criamos um componente do tipo TMemo (ex.: Memo1), e depois usa-se o código seguinte para carregar o conteúdo do ficheiro de texto. Memo1.Lines.LoadFromFile('c:\texto.txt'); // Lines é uma propriedade do tipo TStrings e para salvar de volta: Memo1.Lines.SaveToFile('c:\texto.txt'); Cenário 2: Queremos carregar um ficheiro de texto para uma lista só de leitura para o utilizador, em que cada linha é independente da outra: - Criamos um componente do tipo TListBox (ex.: ListBox1), e depois usa-se o código seguinte para carregar o conteúdo do ficheiro de texto. ListBox1.Items.LoadFromFile('c:\texto.txt'); // Items é uma propriedade do tipo TStrings e para salvar de volta (caso o interface permite a adição de items à ListBox): ListBox1.Items.SaveToFile('c:\texto.txt'); Cenário 3: Queremos que as opções de uma combobox sejam editáveis num ficheiro de texto: - Criamos um componente do tipo TComboBox (ex.: ComboBox1), e depois usa-se o código seguinte para carregar o conteúdo do ficheiro de texto. ComboBox1.Items.LoadFromFile('c:\texto.txt'); // Items é uma propriedade do tipo TStrings Cada linha do ficheiro de texto será uma opção da ComboBox. e para salvar de volta (caso o interface permite a adição de items à ComboBox): ComboBox1.Items.SaveToFile('c:\texto.txt'); Cenario 4: Queremos carregar um ficheiro de texto para ser trabalhado directamente pelo programa, sem necessidade de ser mostrado ao utilizador. Poderíamos criar uma listbox e definir a propriedade Visible para False, mas seria o que eu chamo trabalho de sapateiro. O Delphi possui um componente não-visual, para ser usado em runtime quando precisamos de algo com as características da TStrings. Assim: procedure FazAlgoAoConteudoDoFicheiro(FileName:String); var list:TStringList; begin list:=TStringList.Create; // Cria uma StringList (classe derivada da TStrings try list.LoadFromFile(FileName); // Carrega o texto para a StringList; . . // Faz algo com os dados . list.SaveToFile(FileName); // Volta-se a gravar se desejado Finally list.free; end; end; Carregar ficheiros com uma codificação específica Se precisarmos carregar ou gravar um ficheiro de texto com uma página de códigos específica, o Delphi não nos deixa limitados. Como é costume, há solução para cada pormenor. Existem dois overlays aos métodos LoadFromFile e SaveToFile, mas que aceitam dois parâmetros, em vez de apenas um. Por exemplo, para abrir um ficheiro codificado com a página 850, bastaria isto: memo1.LoadFromFile('c:\teste850.txt',TEncoding.GetEncoding(850)); E para gravar, usar-se-ia o mesmo método... Manipular os dados existentes numa propriedade TStrings: Até agora vimos como carregar e gravar, de forma simples os ficheiros de texto para qualquer componente que possua uma propriedade do tipo TStrings. Para trabalhar com os dados, uma vez carregados, a simplicidade mantém-se: Suponhamos que temos já carregado o nosso ficheiro de texto numa TStringList, e queremos pesquisar em que linha aparece o nosso nome, e por fim mostrar ao utilizador, numa caixa de diálogo, em que linha o nome apareceu). list.LoadFromFile('c:\teste.txt'); // Carrega o ficheiro idx:=list.IndexOf('Nuno Picado'); // Atribui o nº da linha da primeira ocorrência de 'Nuno Picado' à variável idx (Integer). A pesquisa é Case Sensitive] if idx<>-1 // Se a pesquisa de IndexOf não retornar resultados, o valor -1 é retornado then ShowMessage(list[idx]+' apareceu na linha nº '+IntToStr(idx+1)); // Como todos os arrays dinâmicos em Delphi, o primeiro elemento é o 0. Daí o +1 Ou seja, para aceder a uma determinada linha, basta usar o mesmo método que se usa para aceder a elementos de um array (com o índice dentro de parentesis rectos à frente do identificador, com inicio em 0). O método IndexOf pesquisa toda a lista por um valor (string) e retorna o índice, ou o valor -1 caso não seja encontrado. De notar que esta pesquisa é por valores absolutos, ou seja, só é retornado resultado caso o valor passado por parâmetro em IndexOf exista exactamente igual na lista. Caso esta pesquisa absoluta não seja o que desejamos, podemos sempre criar a nossa própria pesquisa: for idx:=0 to List.Count-1 Do // A propriedade Count mostra quantas linhas existem. if pos('NUNO PICADO',UpperCase(List[idx]))>0 // Verifica a existência das palavras NUNO PICADO em toda a linha, Case Insensitive then ShowMessage(list[idx]+' apareceu na linha nº '+IntToStr(idx+1)); Eliminar uma linha: Eliminar uma linha é também tarefa simples. List.Delete(5); // Isto apagará a 6ª linha (6-1=5) Eliminar todas as linhas: List.Clear; // Isto irá limpar todas as linhas da lista Adicionar uma linha: List.Add('Esta é uma nova linha'); // Será adicionada ao fim da lista Inserir uma linha: List.Insert(3); // Isto irá criar uma linha em branco na 4ª posição, movendo todas as outras para baixo Podemos ainda aceder ao conteúdo de todo a lista, como se fosse uma única string, através da propriedade TEXT: ShowMessage(List.Text); // Isto mostra todo o conteúdo da lista numa mensagem Há ainda outros métodos presentes em todos os derivados da TStrings, como a ordenação, mover ou trocar linhas, etc. Mas com isto, é possível perceber com que facilidade se manipulam ficheiros de texto em Delphi... Boas programações... 😄 "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now