View
89
Download
2
Category
Preview:
Citation preview
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 as informaçõ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 em disco 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
Recommended