Baixe o app para aproveitar ainda mais
Prévia do material em texto
Arquivos Estruturas de Dados II – Vanessa Braganholo Entidades } Aplicações precisam armazenar dados sobre as mais diversas entidades, que podem ser concretas ou abstratas } Funcionário de uma empresa (concreto) } Carros de uma locadora de veículos (concreto) } Contas-corrente dos clientes de um banco (abstrato) } Ligações telefônicas dos clientes de uma empresa de telefonia (abstrato) Atributos } Cada uma dessas entidades pode ser descrita por um conjunto de atributos } Funcionário: nome, CPF, data-nascimento, salário } Carro: marca, modelo, ano-fabricação, placa } Conta-Corrente: agência, conta, saldo } Ligações Telefônicas: data, origem, destino, duração } Os atributos também podem ser chamados de campos Registros } Indivíduos dessas entidades possuem um valor para cada um desses atributos (chamados de pares atributo- valor) } Um conjunto de pares atributo-valor que identifica um indivíduo de uma entidade é chamado de registro Exemplos de Registros } Funcionário: <nome, João>, <CPF, 012345678-90>, <data-nascimento, 10/04/1980>, <salário, 3000> } Carro <marca, Honda>, <modelo, Fit>, <ano-fabricação, 2010>, <placa, XYZ0123> } Conta-Corrente <agencia, 0123>, <conta, 123456>, <saldo, 2000> } Ligação Telefônica <data, 01/07/2010>, <origem, 21-2598-3311>, <destino, 21-2589-3322>, <duração, 10’36”> Tabela } Uma tabela é um conjunto ordenado de registros. Uma tabela pode ser armazenada em memória principal ou em memória secundária (disco) } Nesse segundo caso, também costuma ser chamada de arquivo Exemplo: Arquivo de Funcionários Nome CPF Data-‐Nascimento Salário João 012345678-‐90 10/04/1980 3000 Maria 234567890-‐12 25/07/1978 5000 Lúcia 345678901-‐23 27/04/1981 1500 IMPORTANTE: Todos os registros de uma mesma tabela possuem a mesma estrutura (mesmo conjunto de atributos/campos) Problema: encontrar registros } Problema comum de diversas aplicações: encontrar um ou mais registros em uma tabela } Encontrar o empregado Maria } Encontrar todos os empregados que ganham 3000 } Encontrar todos os empregados que nasceram em 27/04/1981 Conceito de Chave } Dados usados para encontrar um registro: chave } Chave: subconjunto de atributos que identifica um determinado registro Chave Primária e Secundária } Chave primária: subconjunto de atributos que identifica unicamente um determinado registro Exemplo: CPF do funcionário ou RG do funcionário } Na hipótese de uma chave primária ser formada por uma combinação de campos, essa combinação deve ser mínima (não deve conter campos supérfulos) } Eventualmente, podemos encontrar mais de uma combinação mínima de campos que forma uma chave primária } Chave secundária: subconjunto de atributos que identificam um conjunto de registros de uma tabela Exemplo: Nome do funcionário Tabelas } Aplicações reais lidam com várias tabelas, cada uma delas representando uma entidade } Uma aplicação de controle bancário precisaria de quais tabelas? Aplicação Bancária } Uma aplicação de controle bancário precisaria de quais tabelas? } Cliente } Agência } Conta-Corrente Certa redundância é necessária } Neste caso, é necessário correlacionar os dados, para que seja possível saber que conta pertence a que agência, e que conta pertence a que cliente } Para isso, é usual repetir algum dado (um código,por exemplo) no outro arquivo } Cliente: CodCliente, Nome, CPF, Endereço } Agência: CodAgencia, NumeroAgencia, Endereco } Conta-Corrente: CodAgencia, CodCliente, CodConta, NumeroConta, Saldo Certa redundância é necessária } Neste caso, é necessário correlacionar os dados, para que seja possível saber que conta pertence a que agência, e que conta pertence a que cliente } Para isso, é usual repetir algum dado (um código,por exemplo) no outro arquivo } Cliente: CodCliente, Nome, CPF, Endereço } Agência: CodAgencia, NumeroAgencia, Endereco } Conta-Corrente: CodAgencia, CodCliente, CodConta, Numero Conta, Saldo Quais são as chaves primárias e secundárias deste exemplo? Aplicação Financeira } Chaves primárias: } Cliente: CodCliente } Agência: CodAgencia } Conta-Corrente: CodAgencia E CodConta } Chaves primárias alternativas: } Cliente: CPF } Agência: NumeroAgencia } Conta-Corrente: NumeroConta } Chaves secundárias: } Cliente: Nome } Agência: Endereço } Conta-Corrente: CodAgencia, CodCliente, Saldo Discussão sobre chaves } Por quê não usar CPF como chave primária de cliente? Por quê os atributos artificiais (código)? Exercício Deseja-se automatizar uma locadora de automóveis. A locadora possui filiais espalhadas por todo país. Cada filial possui um código que a identifica, um telefone e um endereço. Cada filial da locadora sedia um conjunto de veículos que ela aluga. O veículo é identificado por um número sequencial que o distingue dos demais veículos da filial. Para o veículo é importante saber a placa, data de vencimento do seguro, nome do modelo, número de portas e se possui ar-condicionado ou não. Quando um veículo é alugado é fechado um contrato de aluguel. Cada contrato possui um número identificador, uma data de saída do veículo, uma data de retorno provável, para veículos ainda não retornados, e uma data de retorno efetivo, para veículos já retornados. O contrato é feito para um veículo e um cliente. Para os clientes é preciso armazenar seu nome, CPF, endereço, o telefone, bem como o número e data de expiração de seu cartão de crédito. Exercício } Para o cenário das locadoras, identificar: } Entidades } Atributos } Chaves primárias Discussão } Por que não usar uma única tabela? Banco de Dados } Esse conjunto de arquivos pode ser considerado um banco de Dados? Características de um Sistema de Gerência de Banco de Dados } Natureza auto-descritiva do sistema de banco de dados: banco de dados possui um catálogo onde estão descritas as estruturas e tipos de dados de cada tabela e suas restrições – ex. quais são as chaves primárias de cada tabela } Isolamento entre os programas e os dados, e a abstração dos dados: em programação com arquivos a estrutura dos arquivos é embutida dentro das aplicações. Isso não acontece quando se usa banco de dados. } Suporte para as múltiplas visões dos dados: usuários diferentes podem ver porções diferentes dos dados } Compartilhamento de dados e processamento de transações multi-usuários Características de um Sistema de Gerência de Banco de Dados } Natureza auto-descritiva do sistema de banco de dados: banco de dados possui um catálogo onde estão descritas as estruturas e tipos de dados de cada tabela e suas restrições – ex. quais são as chaves primárias de cada tabela } Isolamento entre os programas e os dados, e a abstração dos dados: em programação com arquivos a estrutura dos arquivos é embutida dentro das aplicações. Isso não acontece quando se usa banco de dados. } Suporte para as múltiplas visões dos dados: usuários diferentes podem ver porções diferentes dos dados } Compartilhamento de dados e processamento de transações multi-usuários NÃO É O NOSSO FOCO NESSA DISCIPLINA! Níveis de Organização das tabelas/arquivos } Organização Lógica dos dados: é a visão que o usuário tem dos dados, com base em entidades, seus atributos e seus relacionamentos } Organização Física dos dados: é a maneira pela qual asinformações ficam armazenadas nos dispositivos periféricos (disco, pen-drive, etc.) Dependência entre programas e dados } Os programas de computador são mais ou menos dependentes da organização física dos dados } Eles podem ser classificados em quatro categorias Categoria 1: Programas Dependentes dos Dados } Programas têm acesso aos dados especificando endereços absolutos de células de armazenamento } Se os dados mudarem de lugar, os programas que os acessam precisam ser modificados } Ocorre nas chamadas de baixo nível dos sistemas operacionais } Exemplo: informação sobre espaço livre em um arquivo em um sistema operacional pode ser guardada em um bloco particular do disco Categoria 2: Independência Física dos Dados } Programas acessam a memória pelo nome e não por endereço (memória primária), ou pela posição relativa ao início do arquivo (memória secundária) } O mapeamento (nome → endereço) é feito pelo sistema operacional } Exemplo: programas escritos em linguagens de Terceira Geração que só precisam conhecer a organização lógica dos dados (C, Java, Pascal...) } Programas dependem da estrutura lógica dos arquivos Categoria 3: Independência Lógica Parcial dos Dados } Programas desta categoria podem operar sobre diversos arquivos (com estruturas diferentes) sem serem modificados. } Estes programas buscam a estrutura dos dados nas informações disponíveis no meio do armazenamento e fazem uma adaptação em tempo de execução do programa. } Caso a adaptação ocorresse em tempo de compilação, seria o caso de programas de categoria 2 } Exemplo de operação: ler o próximo registro de um arquivo Categoria 4: Independência Lógica dos Dados } Programas dessa categoria armazenam a descrição dos dados junto com eles } Por isso, os programas não necessitam definir a estrutura dos dados } Exemplo: programas que utilizam SGBDs Operações sobre arquivos } Programas que lidam com arquivos realizam os seguintes tipos de operações sobre eles: } Criação: alocação e inicialização da área de dados, assim como de seus descritores } Destruição: liberação da área de dados e descritores usados na representação da tabela } Inserção: inclusão de novo registro na tabela } Exclusão: remoção de um registro da tabela } Alteração: modificação dos valores de um ou mais atributos/ campos da tabela } Consulta: obtenção dos valores de todos os campos de um registro, dada uma chave de entrada Refrescando a memória… Tutorial sobre Manipulação de Arquivos em Java Fonte: http://download.oracle.com/javase/tutorial/essential/io IDE Java: NetBeans I/O Stream } Um I/O Stream em Java representa uma fonte de entrada ou saída destino } Um stream pode representar diferentes tipos de fonte ou destino: } Arquivos em disco } Dispositivos } Outros programas } Estruturas em memória } … } Suportam diferentes tipos de dados: } Bytes } Tipos primitivos de dados (inteiros, strings, …) } Caracteres } Objetos I/O Stream } Independente de como funcionam internamente, todos os streams seguem um modelo simples de interação com programas } Um stream é uma sequencia de dados } Para leitura: input stream } Para gravação: output stream I/O Input Stream } Um programa utiliza um Input Stream para ler dados de uma fonte, um item de cada vez I/O Output Stream } Um programa utiliza um Output Stream para gravar dados em um destino, um item de cada vez Na nossa disciplina } Fonte e destino são arquivos } Exemplo de arquivo a ser manipulado xanadu.txt In Xanadu did Kubla Khan A stately pleasure-dome decree: Where Alph, the sacred river, ran Through caverns measureless to man Down to a sunless sea. Byte Streams } Permitem realizar entrada e saída de bytes de 8bits ByteStream: Como funciona… Exemplo } Ver arquivo CopyBytes.java } NOTA: Método read() retorna um int ao invés de um byte } Isso acontece para que seja possível o método retornar -1 quando o stream terminar Considerações sobre o exemplo } Sempre feche os streams utilizados } Ao fechá-los, vc libera a memória consumida por eles } Pode ocorrer erro ao abrir o InputStream ou o OutputStream (ou ambos) } Por isso é importante testar se são diferentes de null antes de fechá-los ByteStream } Muito baixo nível } Existem outros tipos de stream para tratar outros tipos de dados } Mas são importantes porque todos os outros são construídos sobre ele } Nosso arquivo exemplo é um arquivo de texto, então vamos modificar o programa um pouco para tratar isso Character Stream } Mesmo princípio de funcionamento do ByteStream } Faz conversão automática da representação dos caracteres em Java (que usa Unicode) para o enconding de caracteres local } Ver aquivo CopyCharacter.java } Principais diferenças entre este exemplo e o anterior: } Uso de FileReader ao invés de FileInputStream } Uso de FileWriter ao invés de FileOutputStream Entrada e Saída } Neste exemplo, o disco é acessado para ler cada caractere do arquivo, e depois novamente para gravar cada caractere } MUITO LENTO!! } Solução: utilizar BufferedStreams } O sistema operacional faz I/O apenas quando o Buffer está vazio I/O Orientada a linhas } Para arquivos texto, é possível ler linhas inteiras de uma só vez, usando um buffer: BufferedReader (para leitura) e PrintWriter (para gravação) } Linha: } delimitada por um CR ou LF ("\r\n") } delimitada por CR ("\r") } delimitada por LF ("\n") } Ver arquivo CopyLines.java Foco da disciplina } Arquivos binários ao invés de arquivos texto } Como implementar um programa que grava registros de funcionários, e depois lê esses registros? } Usar DataStreams } Possuem métodos específicos para ler/gravar tipos específicos (inteiro, string, etc) DataStreams } Exemplo do funcionário } Primeiro problema: em Java não existe o conceito de registro } Solução de contorno: } Criar uma classe Funcionário com os atributos do funcionário Classe Funcionário public class Funcionario { public int codFuncionario; public String nome; public String cpf; public String dataNascimento; public float salario; } NOTA IMPORTANTE: não é uma boa prática de programação utilizar atributos públicos nas classes. Na disciplina, vamos adotar esta opção apenas para simplificar os exemplos. O correto seria implementar métodos get e set para cada atributo. Manipulação } DataStream detecta final de arquivo lançando uma exceção java.io.EOFException } Lógica para testar final de arquivo agora não é mais baseada no teste de valor -1 } Capturar a exceção e fechar o DataStream } Ver arquivo ManipulaFuncionario.java Exercício } Alterar a classe ManipulaFuncionario para ler os dados do funcionário a ser gravado do teclado (atenção: criar uma nova classe! Não sobre-escrever a classe!) } A cada funcionário informado, perguntar se deseja ler os dados de mais um funcionário } Se sim, ler mais um funcionário } Se não, gravar todos os funcionários lidos Orientação a objetos } Exemplo anterior fere os princípios de orientação a objetos } Ideal é dar a responsabilidade de ler registro e gravar registro à classe Funcionário } Ver arquivo FuncionarioOO.java } Ver arquivo ManipulaFuncionarioOO.java Flush } Os métodos que utilizam buffer para gravação só fazem a gravação emdisco quando o buffer está cheio } Às vezes é necessário ter mais controle sobre quando os dados realmente serão gravados } AutoFlush: Algumas classes buffered output (ex. PrintWriter) possuem um atributo autoFlush. Quando este atributo está ligado (true), o buffer é gravado em disco a cada vez que uma operação println é executada } Alternativa: Método flush força gravação do buffer em disco Fonte } http://download.oracle.com/javase/tutorial/essential/io Pratique! } Execute os códigos dos exemplos deste tutorial em casa Exercício } Modifique as classes para lidar com registros de conta- corrente } Dois arquivos: } Agência (Cod, Nome, Gerente) } Conta-Corrente (Cod, CodAgencia, Saldo) } Usuário deve poder escolher o que quer cadastrar } Dados devem ser lidos do teclado } Aplicação deve ter opção de Cadastrar, Ler ou Sair
Compartilhar