Mecanismos de entradas e saídas em Java. A classe File. Streams, Readers, Writers. Composição de canais. Acesso aleatório a ficheiros. Serialização de tipos primitivos e de objectos: a interface Serializable. Elementos não serializáveis: a palavra chave transient. Excepções associadas a entradas e saídas.
Mecanismos de entradas e saídas em Java. A classe File. Streams, Readers, Writers. Composição de canais. Acesso aleatório a ficheiros.
Embora não directamente relacionado com o tópico de entradas e saídas, o processamento de texto pode implicar ordenação de texto em língua natural.
Se forem usados os processos meramente relacionados com a codificação de caracteres, listas de nomes com acentos podem ser ordenadas de forma errónea:
Análise e Síntese de Algoritmos Compiladores Cálculo I Álgebra
A ordem correcta seria:
Álgebra Análise e Síntese de Algoritmos Cálculo I Compiladores
A resolução do problema passa pela utilização dos conceitos relacionados com texto e sensíveis às definições de localização (região e língua natural) e não meramente com codificação de caracteres. No caso concreto deste exemplo, usa-se um comparador especial, Collator, parametrizado com uma instância de Locale (define a forma de ordenação para uma dada língua natural):
Collator & Locale |
---|
import java.text.Collator;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Collections;
public class App {
public static void main(String[] main) {
ArrayList<String> l = new ArrayList<>();
l.add("Análise e Síntese de Algoritmos");
l.add("Compiladores");
l.add("Cálculo I");
l.add("Álgebra");
Collections.sort(l, Collator.getInstance(Locale.getDefault()));
System.out.println(l);
}
}
|
Se o objecto que usa o Collator implementar Serializable, pode ocorrer um problema: Collator não implementa Serializable. Uma solução passa por definir um wrapper que é serializável e que reinicializa o Collator quando lido de disco.
CollatorWrapper.java |
---|
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
class CollatorWrapper implements Comparator<String>, Serializable {
private static final long serialVersionUID = 202110251850L;
private transient Collator _collator = Collator.getInstance(Locale.getDefault());
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
_collator = Collator.getInstance(Locale.getDefault());
}
@Override
public int compare(String s1, String s2) { return _collator.compare(s1, s2); }
}
|
Exemplo de aplicação que usa o wrapper.
App.java |
---|
import java.util.Set;
import java.util.TreeSet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class App {
public static void main(String[] main) {
Set<String> set = new TreeSet<>(new CollatorWrapper());
// add first two elements
set.add("Análise e Síntese de Algoritmos");
set.add("Compiladores");
try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("set.dat")))) {
oos.writeObject(set);
}
catch (IOException e) { e.printStackTrace(); }
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("set.dat")))) {
set = (Set<String>)ois.readObject();
}
catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
// add more elements
set.add("Cálculo I");
set.add("Álgebra");
System.out.println(set);
}
}
|