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