6
20/10/15 1 Arquivos e fluxos Com slides adaptados de Vítor E. Silva Souza ([email protected] ) http://www.inf.ufes.br/ ~ vitorsouza Departamento de Informática Centro Tecnológico Universidade Federal do Espírito Santo Este obra foi licenciada sob uma Licença Creative Commons Atribuição 3.0 Não Adaptada. Arquivos • O que é um arquivo? • Do ponto de vista do SO, todos os arquivos são iguais, independente do seu conteúdo Julho 2013 Desenvolvimento OO com Java 4 Plataformas e sistemas de arquivo • Diferentes sistemas operacionais representam arquivos e caminhos (paths) de diferentes formas: C:\Documents and Settings\User\Arquivo.txt; /home/User/Arquivo.txt. • Java uKliza a classe java.io.File, abstraindo esta representação e provendo portabilidade. // No Windows: File f = new File("C:\\pasta\\arq.txt"); // No Linux/Unix/Mac: File f = new File("/pasta/arq.txt"); A classe java.io.File • Pode representar arquivos ou diretórios: • Possui métodos úteis para manipulação: – canRead(), canWrite(), createNewFile(), delete(), exists(), getName(), getParentFile(), getPath(), isDirectory(), isFile(), isHidden(), lastModified(), length(), list(), listFiles(), mkdir(), mkdirs(), renameTo(), setLastModified(), setReadOnly(), etc. Julho 2013 Desenvolvimento OO com Java 6 File a1 = new File("arq1.txt"); File a2 = new File("/pasta", "arq2.txt"); File d = new File("/pasta"); File a3 = new File(d, "arq3.txt"); Fluxos, leitores e escritores • Até Java 1.4, I/O era feita por: – Fluxos (streams): subclasses de InputStream e OutputStream para leitura/escrita byte a byte; – Leitores (readers) e escritores (writers): subclasses de Reader e Writer para leitura/escrita caractere a caractere (padrão Unicode). • A parKr do Java 5: – Foi criada a classe java.util.Scanner para facilitar a leitura; – Foram adicionados métodos à classe PrintWriter para facilitar a escrita (ex.: printf()). Julho 2013 Desenvolvimento OO com Java 7 Modo de operação • Cria-se o fluxo, leitor, escritor ou scanner e este estará aberto automaKcamente; • UKliza-se operações de leitura e escrita: – Operações de leitura podem bloquear o processo no caso dos dados não estarem disponíveis; – Métodos como available() indicam quantos bytes estão disponíveis. • Fecha-se o fluxo, leitor, escritor ou scanner: – A omissão da chamada ao método close() pode provocar desperdício de recursos ou leitura/escrita incompleta. Julho 2013 Desenvolvimento OO com Java 8

jpalmeida-aula12-arquivos-fluxos · 20/10/15 6 Exemplo de serialização Julho 2013 Desenvolvimento OO com Java 36 public class Info implements Serializable { private String texto;

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

20/10/15

1

Arquivos e fluxos

Com slides adaptados de

Vítor E. Silva Souza

([email protected]) http://www.inf.ufes.br/~ vitorsouza

Departamento de Informática

Centro Tecnológico

Universidade Federal do Espírito Santo

Este obra foi licenciada sob uma Licença Creative Commons Atribuição 3.0 Não Adaptada.

Arquivos•  Oqueéumarquivo?•  DopontodevistadoSO,todososarquivossãoiguais,independentedoseuconteúdo

Julho2013 DesenvolvimentoOOcomJava 4

Plataformasesistemasdearquivo•  Diferentessistemasoperacionaisrepresentamarquivosecaminhos(paths)dediferentesformas:

•  C:\Documents and Settings\User\Arquivo.txt;•  /home/User/Arquivo.txt.•  JavauKlizaaclassejava.io.File,abstraindoestarepresentaçãoeprovendoportabilidade.

Julho2013 DesenvolvimentoOOcomJava 5

// No Windows: File f = new File("C:\\pasta\\arq.txt"); // No Linux/Unix/Mac: File f = new File("/pasta/arq.txt");

Aclassejava.io.File •  Poderepresentararquivosoudiretórios:

•  Possuimétodosúteisparamanipulação:–  canRead(),canWrite(),createNewFile(),delete(),exists(),getName(),getParentFile(),getPath(),isDirectory(),isFile(),isHidden(),lastModified(),length(),list(),listFiles(),mkdir(),mkdirs(),renameTo(),setLastModified(),setReadOnly(),etc.

Julho2013 DesenvolvimentoOOcomJava 6

File a1 = new File("arq1.txt"); File a2 = new File("/pasta", "arq2.txt"); File d = new File("/pasta"); File a3 = new File(d, "arq3.txt");

Fluxos,leitoreseescritores•  AtéJava1.4,I/Oerafeitapor:

–  Fluxos(streams):subclassesdeInputStreameOutputStreamparaleitura/escritabyteabyte;

–  Leitores(readers)eescritores(writers):subclassesdeReadereWriterparaleitura/escritacaractereacaractere(padrãoUnicode).

•  AparKrdoJava5:–  Foicriadaaclassejava.util.Scannerparafacilitaraleitura;

–  ForamadicionadosmétodosàclassePrintWriterparafacilitaraescrita(ex.:printf()).

Julho2013 DesenvolvimentoOOcomJava 7

Mododeoperação•  Cria-seofluxo,leitor,escritorouscannereesteestaráabertoautomaKcamente;

•  UKliza-seoperaçõesdeleituraeescrita:– Operaçõesdeleiturapodembloquearoprocessonocasodosdadosnãoestaremdisponíveis;

– Métodoscomoavailable()indicamquantosbytesestãodisponíveis.

•  Fecha-seofluxo,leitor,escritorouscanner:– Aomissãodachamadaaométodoclose()podeprovocardesperdícioderecursosouleitura/escritaincompleta.

Julho2013 DesenvolvimentoOOcomJava 8

20/10/15

2

Aplicandoopolimorfismo•  Métodosdefinidosnasclassesabstratasedisponíveisemtodaahierarquia:–  InputStream:available(),close(),read(),read(byte[] b),reset(),skip(long l),etc.;

–  OutputStream:close(),flush(),write(int b),write(byte[] b),etc.;

–  Reader:close(),mark(),read(),read(char[] c),ready(),reset(),skip(long l),etc.;

–  Writer:append(char c),close(),flush(),write(char[] c),write(int c),write(String s),etc.

Julho2013 DesenvolvimentoOOcomJava 9

AhierarquiadeI/O•  Sãomaisde40classes,divididasem:

–  Fluxosdeentrada(inputstreams);–  Fluxosdesaída(outputstreams);–  Leitoresdecaracteres(readers);–  Escritoresdecaracteres(writers);– Arquivodeacessoaleatório(randomaccessfile).

•  ClassespodemindicaramídiadeI/Oouaformademanipulaçãodosdados;

•  Podem(devem)sercombinadasparaaKngirmosoresultadodesejado.

Julho2013 DesenvolvimentoOOcomJava 10

Fluxosdeentrada

Julho2013 DesenvolvimentoOOcomJava 11unread

mark / reset

deprecated

deprecated

origem dos dados

lê valores de tipos primitivos

concatena streams

CombinandoFluxos

Julho2013 DesenvolvimentoOOcomJava 12

http://www3.ntu.edu.sg/home/ehchua/programming/java/j5b_io.html

Combinandofluxos

Julho2013 DesenvolvimentoOOcomJava 13

// Lê de um arquivo. FileInputStream fin = new FileInputStream("arquivo.txt"); // Efetua leitura com buffer. BufferedInputStream bin = new BufferedInputStream(fin); // Provê métodos de acesso a tipos de dados. DataInputStream din = new DataInputStream(bin); // Resumidamente: DataInputStream din2 = new DataInputStream(new BufferedInputStream(new FileInputStream("arq.txt")));

fin bin din

Estabelece fonte Faz buffer, permitindo mark/reset

Faz “parsing”/decoding de tipos de dados

bytes bytes Java Primitive Data types

bytes

Exemplocomfluxodeentrada

Julho2013 DesenvolvimentoOOcomJava 14

// Dentro do main. Classe deve importar java.io.*. try { DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("arq.txt"))); String linha; String buffer = new String(); linha = in.readLine(); // Deprecated. while (linha != null) { buffer += linha + "\n"; linha = in.readLine(); // Deprecated. } in.close(); } catch (IOException e) { System.out.println("Erro de I/O"); e.printStackTrace(); }

20/10/15

3

Fluxosdesaída

Julho2013 DesenvolvimentoOOcomJava 15

Exemplocomfluxodesaída

Julho2013 DesenvolvimentoOOcomJava 16

// Dentro do main. Classe deve importar java.io.*. try { DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("arq.txt"))); out.writeBytes("Uma frase..."); out.writeDouble(123.4567); out.close(); } catch (IOException exc) { System.out.println("Erro de IO"); exc.printStackTrace(); }

out bos fos

Codifica tipos primitivos

Faz buffer, permitindo flush

Estabelece alvo

bytes Valores de tipos primitivos

bytes bytes

Arquivosquecontémtexto

Julho2013 DesenvolvimentoOOcomJava 17

•  Estesarquivoscontémsequênciasdebytesquecodificamcaracteres

•  UsamosatabelaASCIIquecontémumvalornuméricoparacadacaracter

•  Comotemosmaisdoque256caracterespossíveisconsiderandojáapenasaslínguaseuropeias,umbytejánãoémaissuficienteparacodificartodoscaracteres

•  ParaistosurgiuUnicode,queéumpadrãobaseparaCharemJava(etambémString)

•  Umnúmero(codepoint)paracadacaracter•  HáváriasformasdesecodificarumChar(Unicode)emumasequênciadebytes

CodificaçõesdiferentesdeCharsUnicode

Julho2013 DesenvolvimentoOOcomJava 18

http://www3.ntu.edu.sg/home/ehchua/programming/java/j5b_io.html

Leitores–Leemsequênciasdecaracteres

Julho2013 DesenvolvimentoOOcomJava 19

Exemplocomleitor

Julho2013 DesenvolvimentoOOcomJava 20

// Dentro do main. Classe deve importar java.io.*. try { BufferedReader breader = new BufferedReader(new FileReader("arq.txt")); String linha; String buffer = new String(); linha = breader.readLine(); while (linha != null) { buffer += linha + "\n"; linha = breader.readLine(); } breader.close(); } catch (IOException e) { System.out.println("Erro de I/O");e.printStackTrace(); }

freader breader

Estabelece fonte, Usa default charset

Faz buffer, permitindo mark/reset

bytes Chars Chars

20/10/15

4

Escritores

Julho2013 DesenvolvimentoOOcomJava 21

Exemplocomescritor

Julho2013 DesenvolvimentoOOcomJava 22

// Dentro do main. Classe deve importar java.io.*. try { BufferedWriter out = new BufferedWriter(new FileWriter("arq.txt")); out.write("Uma frase..."); out.write("" + 123.4567); out.close(); } catch (IOException exc) { System.out.println("Erro de I/O"); exc.printStackTrace(); }

ExemplocomCharsetexplícito

Julho2013 DesenvolvimentoOOcomJava 23

try{BufferedWriterout=newBufferedWriter(newOutputStreamWriter(newFileOutputStream("a.txt"),"UTF-8"));out.write("12345 55.66\n");out.write("Hi,您好!\n");out.flush();}catch(IOExceptionex){ex.printStackTrace();}

Esehouverumaexceção?

Julho2013 DesenvolvimentoOOcomJava 24

// Dentro do main. Classe deve importar java.io.*. try { BufferedWriter out = new BufferedWriter(new FileWriter("arq.txt")); out.write("Uma frase..."); out.write("" + 123.4567); out.close(); } catch (IOException exc) { System.out.println("Erro de I/O"); exc.printStackTrace(); }

Um erro aqui...

o código pula pra cá...

e o escritor não foi fechado.

O problema se repete nos demais exemplos e fica ainda mais complicado quando múltiplos recursos são usados...

UsandomúlKplosrecursos

Julho2013 DesenvolvimentoOOcomJava 25

InputStream in = null; OutputStream out = null; try { in = new FileInputStream(origem); out = new FileOutputStream(destino); byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } catch (FileNotFoundException | IOException ex) { System.out.println("Problemas com a cópia: " + ex); } finally { if (in != null) try { in.close(); } catch (IOException ex) { System.out.println("Problemas com a cópia: " + ex); } finally { if (out != null) try { out.close(); } catch (IOException ex) { System.out.println("Problemas com a cópia: " + ex); } } }

Java7:trywithresources•  GerenciamentoautomáKcoderecursos“fecháveis”:

Julho2013 DesenvolvimentoOOcomJava 26

try (InputStream in = new FileInputStream(origem); OutputStream out = new FileOutputStream(destino);) { byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } catch (FileNotFoundException | IOException ex) { System.out.println("Problemas com a cópia: " + ex); }

20/10/15

5

Acessoaleatório•  Fluxos,leitoreseescritoresfazemapenasacessosequencial;

•  Àsvezesprecisamosdeacessardiferentesposiçõesdoarquivo(ex.:bancodedados):– Umadeterminadaposiçãodoarquivopodeseracessadadiretamente;

–  Tratamentomaiseficientedegrandesvolumesdedados.

•  Aclassejava.io.RandomAccessFileoferecesuportedeleituraeescritaaleatória.

Julho2013 DesenvolvimentoOOcomJava 27

java.io.RandomAccessFile

•  MisturadeDataInputStreamcomDataOutputStream;

•  Nacriação,especifica-seoarquivoeomododeoperação:"r"ou"rw";

•  Usa-semétodosdemanipulaçãodedados:close(),getFilePointer(),length(),read(byte[]),readBoolean(),...,readLong(),readLine(),seek(long),skipBytes(long),write(byte[]),writeBoolean(boolean),...,writeLong(long).

Julho2013 DesenvolvimentoOOcomJava 28

java.util.Scanner

•  NovidadedoJava5.0;•  Facilitaaleituradedados:

–  ConstrutorespodemreceberFile,InputStream,ReadereString;

– DivideemtokenscomuseDelimiter(String);–  FazleituraregionalizadacomuseLocale(Locale);– ObtémdadosdiretamenteemseusKpos,comnext(),nextLine(),nextBoolean(),nextInt(),nextDouble(),etc.

Julho2013 DesenvolvimentoOOcomJava 29

Serialização•  ObjectInputStreameObjectOutputStreamsãofluxosespeciais;

•  Aocontráriodetudomaisquevimos,elesnãoleem/escrevemdadosdeKposprimiKvos;

•  Serializaçãoéoprocessodeconverterumobjetoemumfluxodebitsevice-versa;

•  Serveparagravá-loemdiscoeenviá-lopelaredeparaoutrocomputador.

Julho2013 DesenvolvimentoOOcomJava 33

Serialização•  Problemas:

– Umobjetopodepossuirreferências(ponteiros)paraoutros.Devemos“relaKvizá-las”quandoformosserializaresteobjeto;

– Aorestauraroobjetoasuaformaemmemória,devemosrecuperarasreferênciasaosobjetoscertos.

Julho2013 DesenvolvimentoOOcomJava 34

java.io.Serializable

•  Felizmente,Javajáimplementaestemecanismo;•  BastaqueaclassequedeveserconverKdaimplementeainterfaceSerializable;–  Interfacesemmétodos,“sinalizadora”.

•  Mecanismodeserialização:–  Converteparabytesevice-versa;–  FazedesfazarelaKvizaçãodasreferências;–  Compensadiferençasentresistemasoperacionais;– UsaObjectInputStreameObjectOutputStream.

Julho2013 DesenvolvimentoOOcomJava 35

20/10/15

6

Exemplodeserialização

Julho2013 DesenvolvimentoOOcomJava 36

public class Info implements Serializable { private String texto; private float numero; private Dado dado; public Info(String t, float n, Dado d) { texto = t; numero = n; dado = d; } public String toString() { return texto + "," + numero + "," + dado; } }

Exemplodeserialização

Julho2013 DesenvolvimentoOOcomJava 37

import java.util.Date; public class Dado implements Serializable { private Integer numero; private Date data; public Dado(Integer n, Date d) { numero = n; data = d; } public String toString() { return "(" + data + ":" + numero + ")"; } }

Exemplodeserialização

Julho2013 DesenvolvimentoOOcomJava 38

import java.util.Date; import java.io.*; public class Teste { public static void main(String[] args) throws Exception { Info[] vetor = new Info[] { new Info("Um", 1.1f, new Dado(10, new Date())), new Info("Dois", 2.2f, new Dado(20, new Date())) }; /* Continua... */

Exemplodeserialização

Julho2013 DesenvolvimentoOOcomJava 39

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objs.dat")); out.writeObject("Os dados serializados foram:"); out.writeObject(vetor); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream("objs.dat")); String msg = (String)in.readObject(); Info[] i = (Info[])in.readObject(); in.close(); System.out.println(msg + "\n" + i[0] + "\n" + i[1]); } }

java.io.Serializable

•  Palavrachavetransientparaevitaraserializaçãodeatributos

•  SehouveratributosnãoserializáveisaexceçãoNotSerializableExcepKonserájogada

Julho2013 DesenvolvimentoOOcomJava 40