Vamos dizer que você baixou um torrent. Os arquivos do torrent foram todos acrescidos de um sufixo com o nome do uploader e os espaços foram trocados por "+". Queremos retirar este sufixo e trocar os "+" por espaços.
import java.io.File; import java.io.IOException;
/** * renomeia um arquivo, remove um padrão e substitui por outro * @param arg[0] arquivo ou diretorio * @param arg[1] padrao a ser procurado * @param arg[2] novo valor * @param arg[3] opcional. se igual a "sub" procura nos subdiretórios */ public class RenomeiaArquivos { String padrao; String novoPadrao; boolean subDiretorios = false;
Notem que ele compila e consegue ser executado. Este exemplo rodamos no linux com open-jdk.
Seria interessante que este programa utilize regex para podermos usar wildcard para o nome de arquivo.
Muitas vezes quando desejamos efetuar operações sobre arquivos, como por exemplo, copiar um arquivo de um diretório para outro, queremos ter certeza que não estamos sobrescrevendo o novo pelo antigo. Para saber isto temos que comparar as datas do arquivo de origem com o destino.
Vamos ver uma classe que faz esta comparação.
import java.util.*; import java.io.File;
/** * compara a data de dois arquivos * @param arg[0] arquivo de origem * @param arg[1] arquivo de destino */ public class ComparaDatasArquivos { public static void main(String[] args) { if (args.length < 2) { System.out.println("Uso: java ComparaDatasArquivos arquivo1 arquivo2"); System.exit(0); }
// pega os dois arquivos File f1 = new File(args[0]); File f2 = new File(args[1]);
// pega as datas dos arquivos long d1 = f1.lastModified(); long d2 = f2.lastModified(); String situacao; if (d1 == d2) situacao = "tem mesma data que"; else if (d1 < d2) situacao = "eh mais antigo que"; else situacao = "eh mais novo que"; System.out.println(f1.getName() + " " + situacao + " " + f2.getName()); } }
Compilem e rodem
PS: Notem a construção do if .. else if .. else do final da classe. Quando se tem um comando, não é necessário criar um bloco com { }
Arquivos com formato ZIP são armazenados em um único arquivo compactados (ou diversos arquivos parciais). O framework do Java é capaz de gerar arquivos nos formatos GZIP e ZIP conforme definições das RFC 1950, RFC 1951 e RFC 1952.
As classes que manipulam arquivos ZIP estão em java.util.zip. Estas classes são subclasses de java.io.FilterInputStream e java.io.FilterOutputStream. Desta forma a geração de um arquivo lembra bastante a manipulação de uma stream.
Neste pacote encontramos ainda classe para gerar CRC (cyclic redundancy check checksums).
Um arquivo .zip possui um cabeçalho com informações com o nome dos arquivos e métodos de compressão utilizados. Podemos utilizar ZipInputStream para ler o arquivo zip utilizando construção abaixo:
// encadear a chamada para ZipInputStream com FileInputStream
FileInputStream arquivo = new FileInputStream(nomeDoArquivoZip)
ZipInputStream arquivoZip = new ZipInputStream(arquivo); ZipEntry arquivoCompactado;
// varre o arquivo compactado buscando cada uma das entradas
while ((arquivoCompactado = arquivoZip.getNextEntry()) != null) { /*
arquivoCompactado.toString() --> retorna uma string representando a entrada
arquivoCompactado.getName() --> retorna o nome da entrada (arquivo/diretorio)
arquivoCompactado.isDirectory() --> retorna se a entrada é um diretório
arquivoCompactado.getTime() --> hora da arquivo (entrada)
arquivoCompactado.getSize() --> tamanho do arquivo (entrada) descompactado
arquivoCompactado.getCRC() --> CRC
arquivoCompactado.CompressedSize() --> tamanho do arquivo compactado
// entrada do programa public static void main(String[] args) { ExemploZipInputFrame frame = new ExemploZipInputFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } // ExemploZipInput
/** Esta classe é composta por uma área que apresenta os arquivos texto e permite a descompactação. O arquivo zip pode ser selecionado pelo menu. */ class ExemploZipInputFrame extends JFrame { // tamanho da tela public static finalint DEFAULT_WIDTH = 600; public static finalint DEFAULT_HEIGHT = 400;
private JComboBox<String> comboArquivosNoZip; private JTextArea areaArquivoTexto; // local para apresentar os arquivos texto private JButton btnExtrair; // private String nomeArquivoZip; public ExemploZipInputFrame() { setTitle("Exemplo de utilizacao de java.util.zip"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// menu JMenuBar menuBar = new JMenuBar(); // 1. Arquivo JMenu menu = new JMenu("Arquivo"); JMenuItem mnuAbrir = new JMenuItem("Abrir"); menu.add(mnuAbrir); mnuAbrir.addActionListener(new ActionAbrirZip()); // classe definida abaixo JMenuItem mnuSair = new JMenuItem("Sair"); menu.add(mnuSair); mnuSair.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); menuBar.add(menu); setJMenuBar(menuBar);
// adiciona componentes no Frame areaArquivoTexto = new JTextArea(); comboArquivosNoZip = new JComboBox<String>(); comboArquivosNoZip.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { String nomeArquivo = (String) comboArquivosNoZip.getSelectedItem(); if (nomeArquivo.endsWith(".txt") || nomeArquivo.endsWith(".java")) { carregaArquivoNaTextArea(nomeArquivo); } } }); add(comboArquivosNoZip, BorderLayout.NORTH); add(new JScrollPane(areaArquivoTexto), BorderLayout.CENTER); btnExtrair = new JButton("Extrair"); btnExtrair.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { // descompacta o conteudo descompactaArquivo((String) comboArquivosNoZip.getSelectedItem()); } }); add(btnExtrair, BorderLayout.SOUTH); } // Construtor ExemploZipInputFrame
/** Classe que realiza ação de "Abrir" do menu */ private class ActionAbrirZip implements ActionListener { public void actionPerformed(ActionEvent event) { // seleciona o arquivo Zip JFileChooser arquivoEscolhido = new JFileChooser(); arquivoEscolhido.setCurrentDirectory(new File(".")); FiltrosDeArquivos filtro = new FiltrosDeArquivos(); filtro.adicionarExtensao(".zip"); filtro.adicionarExtensao(".jar"); filtro.setDescription("Arquivos ZIP"); arquivoEscolhido.setFileFilter(filtro); int escolha = arquivoEscolhido.showOpenDialog(ExemploZipInputFrame.this); if (escolha == JFileChooser.APPROVE_OPTION) { nomeArquivoZip = arquivoEscolhido.getSelectedFile().getPath(); ProcuraNoArquivoZip(); } } } // ActionAbrirZip
/** Lista entradas do arquivo ZIP e preenche o conteudo no combobox */ public void ProcuraNoArquivoZip() { comboArquivosNoZip.removeAllItems(); try { ZipInputStream arquivoZip = new ZipInputStream(new FileInputStream(nomeArquivoZip)); ZipEntry entradaNoZip = null; while ((entradaNoZip = arquivoZip.getNextEntry()) != null) { comboArquivosNoZip.addItem(entradaNoZip.getName()); arquivoZip.closeEntry(); } arquivoZip.close(); } catch (IOException e) { e.printStackTrace(); } }
/** Lê o conteúdo do arquivo para a área @param nome do arquivo compactado (entrada do zip) */ public void carregaArquivoNaTextArea(String nome) { BufferedReader arquivoLido = null; try { areaArquivoTexto.setText(""); // apaga o conteudo da área de texto ZipInputStream arquivoZip = new ZipInputStream(new FileInputStream(nomeArquivoZip)); ZipEntry entradaNoZip = null; // varre as entradas // acha entrada = "nome" while ((entradaNoZip = arquivoZip.getNextEntry()) != null) { if (entradaNoZip.getName().equals(nome)) { // se achou ... le para área de texto arquivoLido = new BufferedReader(new InputStreamReader(arquivoZip)); String linhaLida; while ((linhaLida = arquivoLido.readLine()) != null) { areaArquivoTexto.append(linhaLida); areaArquivoTexto.append("\n"); } } arquivoZip.closeEntry(); } arquivoZip.close(); } catch (IOException e) { e.printStackTrace(); } }
public void descompactaArquivo(String nome) { try { areaArquivoTexto.setText(""); // apaga o conteudo da área de texto ZipInputStream arquivoZip = new ZipInputStream(new FileInputStream(nomeArquivoZip)); ZipEntry entradaNoZip = null; // acha entrada = "nome" while ((entradaNoZip = arquivoZip.getNextEntry()) != null) { if (entradaNoZip.getName().equals(nome)) { BufferedOutputStream arquivoDescompactado = new BufferedOutputStream(new FileOutputStream(nome)); for(int i = arquivoZip.read(); i != -1; i = arquivoZip.read() ) { arquivoDescompactado.write(i); } arquivoDescompactado.close(); } arquivoZip.closeEntry(); } arquivoZip.close(); } catch (IOException e) { e.printStackTrace(); } }
} // ExemploZipInputFrame
/** Esta classe cria um filtro para localizar os arquivos texto Utilizado em JFileChooser quando tenta selecionar um arquivo em ABRIR */ class FiltrosDeArquivos extends FileFilter {
private String descricao = ""; // guarda a lista de extensões suportadas private ArrayList<String> extensoesArquivos = new ArrayList<String>();
/** adiciona uma extensão no filtro @param extensão do arquivo tipo ".txt" ou "txt" */ public void adicionarExtensao(String e) { if (!e.startsWith(".")) { // acrescenta o ponto e = "." + e; } extensoesArquivos.add(e.toLowerCase()); }
/** Armazena a descrição @param desc: uma descricao para o conjunto de filtros */ public void setDescription(String desc) { descricao = desc; }
/** Returna a descricao @return descricao */ public String getDescription() { return descricao; }
/** Indica que pode selecionar a entrada */ public boolean accept(File f) { if (f.isDirectory()) return true; String name = f.getName().toLowerCase();
// verifica se a extensão passa no filtro for (String e : extensoesArquivos) { if (name.endsWith(e)) return true; } return false; // não achou }
Se lembrarmos da definição de Data que representa o número de milisegundos que passaram deste 1º de Janeiro de 1970 00:00:00.000 GMT. Temos que as operações operações de adicionar ou substrair tempos podem ser manuseadas como operações matemáticas com inteiros:
import java.util.Date;
public class ExemploData3 { public static void main(String[] args) { Date agora = new Date(); long t = agora.getTime(); // 7 dias atrás: // equivale a achar t menos // 7 dias x 24 horas x 60 minutos x 60 segundos x 1000 milisegundos Date seteDias = new Date( t - 7 * 24 * 60 * 60 * 1000); System.out.println("Sete dias atras era " + seteDias); // daqui a sete dias seteDias = new Date( t - 7 * 24 * 60 * 60 * 1000); System.out.println("Daqui a sete dias serao " + seteDias); } }
Esta é uma classe funcional mas não é a melhor forma de realizar operações sobre datas. O Java possui uma classe denominada java.util.Calendar que permite trabalhar melhor com estes valores:
public static void main(String[] args) { Calendar data = Calendar.getInstance( ); // formatação a ser utilizada para apresentação das datas SimpleDateFormat sfmt = new SimpleDateFormat("dd/MM/yyyy '-' hh:mm:ss"); System.out.println("data (agora): " + sfmt.format(data.getTime())); // obter 2 anos atras Calendar doisAnosAtras = data; doisAnosAtras.add(Calendar.DAY_OF_YEAR, -(365*2)); System.out.println("dois anos atras : " + sfmt.format(doisAnosAtras.getTime())); Calendar doisAnosAtrasSegundaOpcao = data; doisAnosAtrasSegundaOpcao.add(Calendar.YEAR, -2); System.out.println("dois anos atras (segunda opcao): " + sfmt.format(doisAnosAtrasSegundaOpcao.getTime())); // compara as datas // existe um método Calendar.before(data) veja na documentação if (doisAnosAtras.after(data)) { System.out.println("doisAnosAtras tem data posterior a data"); } else { System.out.println("doisAnosAtras tem data anterior a data"); } if (doisAnosAtrasSegundaOpcao.equals(doisAnosAtras)) { System.out.println("doisAnosAtrasSegundaOpcao igual a doisAnosAtras"); } else { System.out.println("doisAnosAtrasSegundaOpcao diferente de doisAnosAtras"); } } }
Anteriormente à especificação JDK 1.1, a classe Date tinha várias funções. Atualmente esta classe representa um instante no tempo contendo data e hora com precisão de até milisegundos. É necessário a utilização de duas classes adicionais DateFormat e Calendar para permitir a formatação da apresentação da data e para realizar a conversão de datas.
Os formatos dos construtores desta classe são:
Date()
Date(long data)
data é um inteiro que representa a quantidade de milisegundos contados a partir de 01/01/1970.
Os outros formatos para os construtores não devem ser utilizados (são considerados deprecated). Para o nosso exemplo utilizarei a classe SimpleDateFormat. Esta classe utiliza um padrão de formatação que é montada como uma string. Existem diversas letras de formatação, que estão resumidas abaixo:
Para colocar um texto que não será interpretado, basta escrevê-lo entre aspas simples ('). Veja no exemplo abaixo como escrevemos as. A repetição das letras gera variações na interpretação do formato pelo Java. Por exemplo, se utilizamos MMM temos o mês em texto na forma de uma abreviatura, se forma MMMM temos por extenso completo, M temos o mês em número, e finalmente MM temos o mês no formato numérico com 2 dígitos.
Vamos ver um exemplo simples para acessar um banco de dados em MS Access. Para isto temos que realizar 6 passos indicados na classe abaixo:
import java.awt.*;
import java.sql.*; public class Connect { public static void main(String[] av) { // teste é o nome da fonte de dados no ODBC String dbURL = "jdbc:odbc:teste"; try { // 1. carregar o driver de acesso ao banco de dados que desejamos // neste caso é a bridge para ODBC: jdbc-odbc bridge driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.println("Abrindo conexao com "+dbURL);
// 2. abrir a conexão // os parâmetros são: // URL, usuario, senha Connection conn = DriverManager.getConnection(dbURL, "admin", "");
// Se o objeto SQLWarning estiver disponivel, // apresentar na tela os avisos SQLWarning warn = conn.getWarnings( ); while (warn != null) { // podem existir diversos avisos System.out.println("SQLState: " + warn.getSQLState( )); System.out.println("Messagem: " + warn.getMessage( )); System.out.println("Vendor: " + warn.getErrorCode( )); System.out.println(""); warn = warn.getNextWarning( ); }
// 3. criar um objeto tipo Statement que será utilizado //para buscar os dados do banco de dados Statement stmt = conn.createStatement( );
// 4. executar a query para buscar os dados ResultSet rs = stmt.executeQuery("select * from Tabela1");
// 5. mostrar resultados while (rs.next()) { int id = rs.getInt("codigo"); String s = rs.getString("descricao"); Date dt = rs.getDate("data"); System.out.println("Codigo = "+Integer.toString(id)); System.out.println(" Desc = "+s); System.out.println(" Data = "+dt.toString()); }
// 6. fechar os objetos rs.close(); stmt.close(); conn.close();
} catch (ClassNotFoundException e) { System.out.println("Nao foi possivel carregar o driver " + e); } catch (SQLException e) { System.out.println("Acesso ao banco de dados falhou " + e); } } }
Vejamos como funciona a classe:
Para que a classe funcione é necessário criar uma entrada no gerenciador de fontes de dados do ODBC como indicado na figura abaixo: