entrada e saída de arquivos em c#- parte1

15
Operações com arquivos A Microsoft forneceu modelos de objetos muito intuitivos para: Explorar a estrutura de diretórios, encontrar arquivos e pastas e checar suas propriedades Mover, copiar e deletar arquivos e pastas Leitura e escrita de arquivos texto Leitura e escrita de arquivos binários Gerenciamento do sistema de arquivos As classes que são utilizadas para navegar pelo sistema de arquivos e realizar operações, como mover, copiar, e deletar arquivos, são mostradas na figura 1. O namespace de cada classe é mostrado em parênteses abaixo do nome da classe. A lista a seguir explica a função de cada classe: FileSystemInfo classe base que representa qualquer sistema de arquivos File e FileInfo classes que representam um arquivo Directory e DirectoryInfo classes que representam uma pasta Path classe que contém membros que ajudam a manipular nomes de caminhos de arquivos

Transcript of entrada e saída de arquivos em c#- parte1

Page 1: entrada e saída de arquivos em c#- parte1

Operações com arquivos

A Microsoft forneceu modelos de objetos muito intuitivos para:

Explorar a estrutura de diretórios, encontrar arquivos e pastas e checar suas propriedades

Mover, copiar e deletar arquivos e pastas

Leitura e escrita de arquivos texto

Leitura e escrita de arquivos binários

Gerenciamento do sistema de arquivos

As classes que são utilizadas para navegar pelo sistema de arquivos e realizar operações, como mover, copiar, e deletar arquivos, são mostradas na figura 1. O namespace de cada classe é mostrado em parênteses abaixo do nome da classe.

A lista a seguir explica a função de cada classe:

FileSystemInfo classe base que representa qualquer sistema de arquivos

File e FileInfo classes que representam um arquivo

Directory e DirectoryInfo classes que representam uma pasta

Path classe que contém membros que ajudam a manipular nomes de caminhos de arquivos

Page 2: entrada e saída de arquivos em c#- parte1

Figura 1. Hierarquia de classes para manipulação de arquivos e pastas

Classes DotNet que representam arquivos e pastas

Você deve ter notado na lista mostrada que há duas classes usadas para representar uma pasta e duas classes para representar um arquivo. Qual delas você deve utilizar vai depender muito de quantas vezes você precisa acessar o arquivo ou pasta.

As classes Directory e File contêm apenas métodos estáticos (métodos de classe) e nunca são instanciadas (você não cria objetos a partir delas). Você usa essas classes fornecendo um caminho para o sistema de arquivos apropriado sempre que você chama um de seus métodos. Se você quer realizar uma operação em uma pasta ou um arquivo então usar essas classes é mais eficiente, porque isso economiza o tempo de criar objetos.

As classes DirectoryInfo e FileInfo implementam basicamente os mesmo métodos que Directory e File, assim como propriedades, mas seus métodos não são estáticos. Você precisa instanciar essas classes antes de utilizá-las. Isso significa que essas classes são mais interessantes no caso em que você deseja realizar várias operações usando o mesmo objeto.

Vejamos uma comparação entre as duas abordagens:

FileInfo meuArquivo = new FileInfo(@“c:\program files\my program\readme.txt”);

Object(System)

MarshalByRefObject (System)

Directory (System.IO)

File(System.IO)

Path(System.IO)FileSystemInfo

(System.IO)

DirectoryInfo (System.IO)

FileInfo(System.IO)

Page 3: entrada e saída de arquivos em c#- parte1

meuArquivo.CopyTo(@“d:\copies\readme.txt”);

Tem o mesmo efeito de:

File.Copy(@“c:\program files\my program\readme.txt”, @“d:\copies\readme.txt”);

O primeiro fragmento de código será sutilmente mais lento ao ser executado, porque é necessário instanciar um objeto FileInfo, meuArquivo, mas, em compensação, ele deixa meuArquivo pronto para que você possa realizar outras ações com ele. No segundo exemplo, não foi necessário criar uma instância de um objeto para copiar o arquivo.

Para instanciar as classes FileInfo ou DirectoryInfo você fornece um parâmetro para o construtor da classe, que é uma string contendo o caminho do arquivo ou pasta. O primeiro exemplo faz isso para um arquivo. Vejamos como seria para uma pasta.

DirectoryInfo minhaPasta = new DirectoryInfo(@“c:\program files”);

Se o caminho representar um objeto que não existe, então embora nada aconteça na hora da instanciação, uma exceção será lançada na hora que você tentar utilizar o objeto chamando algum método ou propriedade dele. Uma forma de saber se o objeto existe, e se é do tipo apropriado, é utilizar a propriedade Exists:

FileInfo teste = new FileInfo(@“c:\windows”);MessageBox.Show(teste.Exists.ToString());

A propriedade Exists retorna true caso o objeto exista e seja do mesmo tipo que você instanciou. Ou seja, se você pediu um arquivo chamado “windows” no “c:\” (como no exemplo) e se ele encontrar um arquivo com esse nome, ela retornará true. Contudo, se ao invés de encontrar um arquivo, for encontrada uma pasta chamada “windows” então ela retornará false porque foi pedido um arquivo e não uma pasta.

Tendo conseguido definir se arquivo ou pasta existe, você pode obter informações (usando as classes FileInfo e DirectoryInfo) sobre o arquivo ou pasta usando as propriedades mostradas a seguir:

Nome DescriçãoCreationTime Momento em que o arquivo ou

pasta foi criadaDirectoryName (apenas na FileInfo)

Caminho completo da pasta que contém o arquivo

Page 4: entrada e saída de arquivos em c#- parte1

Parent (apenas na DirectoryInfo) A pasta pai da pasta especificadaExists Se o arquivo ou pasta existeExtension Extensão do arquivo, ou branco se

for pastaFullName Caminho completo do arquivo ou

da pastaLastAccessTime Última vez que o arquivo ou a

pasta foi acessadaLastWriteTime Última vez que o arquivo ou a

pasta foi modificadaName O nome do arquivo ou da pastaRoot (apenas na DirectoryInfo) O diretório raiz (unidade) do

caminho para a pastaLength (apenas na FileInfo) O tamanho do arquivo em bytes

Você também pode realizar ações no arquivo ou na pasta usando os métodos a seguir:

Nome FunçãoCreate() Cria uma pasta ou um arquivo

vazio com um nome dado como parâmetro. Para um FileInfo esse método retorna um objeto de arquivo que permite que você escreva nele (veremos isso mais à frente).

Delete() Exclui o arquivo ou a pasta. Para pastas há uma para exclusão de todo o conteúdo (sub-pastas ou somente o conteúdo da pasta dada)

MoveTo() Move e/ou renomeia uma pasta ou arquivo

CopyTo() (Apenas para FileInfo) Copia o arquivo. Note que não há método de cópia para pastas.

GetDirectories() (Apenas para DirectoryInfo) Retorna um array de objetos DirectoryInfo representando todas as sub-pastas contidas em uma pasta.

GetFiles() (Apenas para DirectoryInfo) Retorna um array de objetos FileInfo representando todos os arquivos contidos em uma pasta.

Page 5: entrada e saída de arquivos em c#- parte1

GetFileSystemInfos() (Apenas para DirectoryInfo) Retorna objetos FileInfo e DirectoryInfo representando todos os objetos (arquivos e pastas) contidas em uma pasta, como um array de referências do tipo FileSystemInfo.

Repare que as listas acima contêm apenas os principais métodos e propriedades.

A classe Path

A classe Path não é uma classe instanciável. Ao invés disso, ela expõe alguns métodos estáticos que fazem as operações com strings de caminhos (de arquivos e pastas) mais fáceis.

Por exemplo, o fragmento de código a seguir utiliza o método Path.Combine() para unir um caminho de pasta com um nome de arquivo:

DirectoryInfo dirInfo = new DirectoryInfo(@“c:\Upload\Documents”);string strArquivo = “teste.txt”;string strCaminho = Path.Combine(dirInfo.FullName, arquivo);

A tabela a seguir mostra os principais métodos da classe Path.

Nome FunçãoCombine() Combina um caminho com um

nome de arquivo ou pastaChangeExtension() Modifica a extensão atual do

arquivo na string. Se nenhuma extensão for especificada então a extensão atual será removida.

GetDirectoryName() Retorna todos as informações de uma pasta, a qual esteja explicitada entre o primeiro e o último caractere separador de pastas (“\”)

GetFileName() Retorna apenas o pedaço do caminho que é o nome do arquivo

GetFileNameWithouExtension() Retornar apenas o pedaço do caminho que é o nome do arquivo mas sem a extensão

Page 6: entrada e saída de arquivos em c#- parte1

GetFullPath() Transforma um caminho relativo em caminho absoluto usando a pasta atual como referência. Por exemplo, se “c:\temp” é a pasta atual, então chamar GetFullPath() de um nome de arquivo como “teste.txt” retornará “c:\temp\teste.txt”.

GetPathRoot() Obtém uma string com a pasta raiz (por exemplo, “c:\”) de um caminho absoluto. Se o caminho for relativo, retorna nulo (null)

HasExtension() Retorna true se o caminho termina com uma extensão e false caso contrário.

IsPathRooted() Retorna true se o caminho é absoluto e false se for um caminho relativo.

Embora a classe Path contenha métodos para aprofundar um caminho (adicionando pastas ao caminho), ele não fornece métodos para o contrário (remover pastas de um caminho). Contudo, é possível contornar essa limitação usando o método Combine() com caminho relativo “..”, que significa “mova para uma sub-pasta acima na hierarquia”. Veja o exemplo a seguir:

string strCaminho = @“c:\temp\subpasta”;

strCaminho = Path.Combine(strCaminho, “..”);//agora strCaminho contém a string “c:\temp\subpasta\..”

strCaminho = Path.GetFullPath(strCaminho);//strCaminho agora contém a string “c:\temp”

Obs.: Na maioria dos casos, uma exceção será lançada se você utilizar os métodos da classe Path com caminhos com caracteres inválidos. Contudo, caracteres curingas (* ou ?) são aceitos se causar exceções.

Estudo de caso: Um navegador de arquivos

Vamos agora colocar a mão na massa e criar um exemplo de uma aplicação C# chamada Navegador de Arquivos que apresenta uma interface simples com o usuário (Windows Forms) que permitirá que o usuário navegue pelo sistema de arquivos, e veja a data e hora de criação, data e hora do último acesso, data e hora da última modificação, e tamanho dos arquivos.

Page 7: entrada e saída de arquivos em c#- parte1

A aplicação funcionará assim: você digita o nome da pasta ou do arquivo na caixa de texto principal no topo da janela e clica o botão “Mostrar”. Se você digitou um caminho para uma pasta, seu conteúdo será listado nas caixas de listagens. Se você digitou um caminho para um arquivo, seus detalhes serão mostrados nos rótulos no assoalho da janela e o conteúdo da sua pasta será mostrado nas caixas de listagem.

A figura 2 mostra o layout da aplicação Navegador de Arquivos.

O usuário poderá facilmente navegar pelo sistema de arquivos clicando em qualquer pasta na caixa de listagem do lado direito para ver o conteúdo dessa pasta ou clicar no botão “Subir” para acessar a pasta pai da pasta atual.

Nós criamos o projeto como uma aplicação Windows padrão C# no Visual Studio DotNet, e adicionamos os vários, rótulos, caixas de texto, caixas de listagem.

É necessário indicar que vamos utilizar o namespace System.IO.

using System.IO;

É necessário fazer isso para todos os sistemas relacionados com arquivos que criarmos.

Na classe Form1, vamos criar um atributo para armazenar o caminho da pasta que estiver sendo mostra no momento.

private string strCaminhoPastaAtual;

Page 8: entrada e saída de arquivos em c#- parte1

Figura 2. O navegador de arquivos

Em seguida vamos criar tratadores de eventos para os eventos que possam ser gerados pelo usuário.

Clique do usuário no botão “Mostrar”. Temos que testar se o que o usuário digitou na caixa de texto é um caminho de arquivo ou de pasta. Se for uma pasta listaremos os arquivos e sub-pastas dessa pasta nos caixas de listagens. Se for um arquivo, nós faremos o mesmo para a pasta que contém o arquivo, mas também devemos mostrar as propriedades do arquivo nos rótulos.

Usuário clica no nome do arquivo na caixa de listagem de arquivos. Nesse caso, mostramos as propriedades do arquivo clicado nos rótulos.

Page 9: entrada e saída de arquivos em c#- parte1

Usuário clica no nome do folder na caixa de listagem de pastas. Nesse caso limpamos todos os controles e então mostramos o conteúdo dessa pasta nas caixas de listagens.

Usuário clica no botão “Subir”. Nesse caso, nós limpamos todos os controles e então mostramos o conteúdo da pasta pai da pasta atual.

É interessante criarmos métodos (funções) que realizem as tarefas principais. Primeiramente, vamos criar um método que limpa o conteúdo dos controles.

public void LimpaCampos(){

listBox1.Items.Clear();listBox2.Items.Clear();textbox1.Text = “”;label2.Text = “”;label4.Text = “”;label6.Text = “”;label8.Text = “”;label10.Text = “”;

}

Em seguida, definimos um método, MostraInfoArquivo(), que mostra as informações de um dado arquivo nos rótulos. Esse método recebe um parâmetro, o caminho completo do arquivo, como string, e ele cria um objeto FileInfo baseado nesse caminho:

public void MostraInfoArquivo(string strCaminho){

FileInfo arquivo = new FileInfo(strCaminho);if (!arquivo.Exists){

throw new FileNotFoundException (“Arquivo não encontrado: “ + strCaminho);

}else{

label2.Text = arquivo.Name;label4.Text = arquivo.Length.ToString() + “bytes”;label6.Text =

arquivo.CreationTime.ToLongTimeString();label8.Text =

arquivo.LastAccessTime.ToLongDateString();label10.Text =

arquivo.LastWriteTime.ToLongDataSting();

Page 10: entrada e saída de arquivos em c#- parte1

}

Repare que tomamos a precaução de lançar um exceção se houver algum problema em localizar o arquivo no local especificado. A exceção será tratada na rotina que chama esse método. Finalmente, definiremos o método ListaPasta(), que mostra o conteúdo de uma determinada pasta em duas caixas de listagem. O caminho completo do arquivo é passado como parâmetro para esse método.

public void ListaPasta(string strCaminho){

DirectoryInfo pasta = new DirectoryInfo (strCaminho);if (!pasta.Exists){

throw new DirectoryNotFoundException (“Pasta não encontrada: “ + strCaminho);

}else{

LimpaCampos();textBox1.Text = pasta.FullName;

//lista todas as sub-pastas da pastaforeach (DirectoryInfo proximaSubPasta in

pasta.GetDirectories()){

listBox1.Items.Add(proximaSubPasta.Name);}

//lista todos os arquivos na pastaforeach (FileInfo proximoArquivo in

pasta.GetFiles()){

listBox2.Items.Add(proximoArquivo.Name);}

}} Agora podemos cuidar dos tratadores de eventos. O tratador de evento que gerencia o evento de clique no botão “Mostrar” é o mais complexo, porque ele precisa cuidar de três possibilidades diferentes para o texto que o usuário coloca na caixa de texto. Pode ser o nome de um arquivo, o nome de uma pasta, ou texto inútil:

public void OnButton1_ButtonClick(object sender, EventArgs e){

Page 11: entrada e saída de arquivos em c#- parte1

try{

string strCaminho = textBox1.Text;DirectoryInfo pasta = new DirectoryInfo(strCaminho);if (pasta.Exists){

//é pastaListaPasta(pasta.FullName);return;

}FileInfo arquivo = new FileInfo(strCaminho);if (arquivo.Exists){

//é arquivoListaPasta(arquivo.Directory.FullName);int index = listBox2.Items.IndexOf(arquivo.Name);listBox2.SetSelected(index, true);return;

}

//é texto inútilthrow new FileNotFoundException(“Não há arquivo ou pasta com esse nome: “ + strCaminho);

}catch(Exception objExcecao){

MessageBox.Show(objExcecao.Message);}

}

Estabelecemos que se o texto fornecido representar uma pasta ou um arquivo, criamos o objeto respectivo e examinamos se ele existe. Se nenhum existir, então lançamos uma exceção. Se ele for pasta, chamamos o ListaPasta() para popular as caixas de listagem. Se ele for arquivo, populamos as caixas de listagem com os dados da pasta pai do arquivo. Então programaticamente fazemos o nome do arquivo ficar selecionado na caixa de listagem de arquivos. Isso tem o mesmo efeito de o usuário clicar no nome do arquivo na caixa de listagem.

O código a seguir é o tratador de evento que é chamado quando um item da caixa de listagem de arquivos é selecionada, seja pelo usuário, ou como indicado acima, por nós mesmos, programaticamente. Ele simplesmente constrói o caminho completo do arquivo selecionado, e o passa para a função MostraInfoArquivo() que foi criada anteriormente.

Page 12: entrada e saída de arquivos em c#- parte1

public void OnListBox1Selected(object sender, EventArgs e){

try{

string strSelecionado= listBox1.SelectedItem.ToString();string strCaminho = Path.Combine(strCaminhoPastaAtual, strSelecionado);MostraInfoArquivo(strCaminho);

}catch(Exception objExcessao){

MessageBox.Show(objExcessao.Message);}

}

O tratador de eventos para seleção de pasta na caixa de listagem de pastas é implementado de forma muito parecida, exceto que nesse caso, nós chamamos o método ListaPasta() para atualizar o conteúdo das caixas de listagem:

public void OnListBox2FoldersSelected(object sender, EventArgs e){

try{

string strSelecionado = listBox2.SelectedItem.ToString();string strCaminho = Path.Combine(strCaminhoPastaAtual, strSelecionado);DisplayFolderList(strCaminho);

}catch(Exception objExcecao){

MessageBox.Show(objExcecao.Message);}

}

Finalmente, quando o botão “Subir” for clicado, ListaPasta() também deve ser chamado, porém dessa vez precisamos obter o caminho para a pasta pai da pasta atual. Isso é feito com o a propriedade DirectoryName que retorna o caminho para a pasta pai.

public void OnButton2ButtonClick(object sender, EventArgs e){

try{

Page 13: entrada e saída de arquivos em c#- parte1

string strCaminhoPasta = new FileInfo(strCaminhoPastaAtual).DirectoryName;ListaPasta (strCaminhoPasta);

//atualiza a pasta atualstrCaminhoPastaAtual = strCaminhoPasta;

}catch(Exception objExcecao){

MessageBox.Show(objExcecao.Message);}

}