File IO

Operações com arquivos são uma funcionalidade importante do programa. Esta lição aborda IO de arquivos em Java.

Classe File

A classe File é usada para operar em arquivos e diretórios.

Criando Objetos File

JAVA
import java.io.File;

// Método 1: String de caminho
File file1 = new File("test.txt");

// Método 2: Caminho pai + nome do arquivo
File file2 = new File("/home/user", "test.txt");

// Método 3: Objeto File + nome do arquivo
File dir = new File("/home/user");
File file3 = new File(dir, "test.txt");

Métodos Comuns

Método Descrição
exists() Existe
isFile() É arquivo
isDirectory() É diretório
getName() Obter nome do arquivo
getPath() Obter caminho
getAbsolutePath() Obter caminho absoluto
length() Tamanho do arquivo (bytes)
createNewFile() Criar arquivo
mkdir() Criar diretório
mkdirs() Criar diretórios aninhados
delete() Deletar
list() Listar conteúdo do diretório

Exemplo: Operações com Arquivos

JAVA
import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("test.txt");
        
        // Criar arquivo
        if (!file.exists()) {
            file.createNewFile();
            System.out.println("Arquivo criado com sucesso");
        }
        
        // Informações do arquivo
        System.out.println("Nome: " + file.getName());
        System.out.println("Caminho: " + file.getPath());
        System.out.println("Caminho absoluto: " + file.getAbsolutePath());
        System.out.println("Tamanho: " + file.length() + " bytes");
        System.out.println("É arquivo: " + file.isFile());
        System.out.println("É diretório: " + file.isDirectory());
        
        // Deletar arquivo
        // file.delete();
    }
}
▶ Experimente

Exemplo: Operações com Diretórios

JAVA
import java.io.File;

public class DirectoryDemo {
    public static void main(String[] args) {
        // Criar diretório
        File dir = new File("testdir/subdir");
        dir.mkdirs();
        System.out.println("Diretório criado: " + dir.getAbsolutePath());
        
        // Listar conteúdo do diretório
        File parent = new File("testdir");
        String[] files = parent.list();
        if (files != null) {
            for (String name : files) {
                System.out.println("  " + name);
            }
        }
        
        // Percorrer diretório
        File[] fileArray = parent.listFiles();
        if (fileArray != null) {
            for (File f : fileArray) {
                String type = f.isDirectory() ? "[DIR]" : "[ARQ]";
                System.out.println(type + " " + f.getName());
            }
        }
    }
}
▶ Experimente

Leitura/Escrita de Arquivos

BufferedReader Ler Arquivo

JAVA
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile {
    public static void main(String[] args) {
        // try-with-resources fecha recursos automaticamente
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Falha na leitura: " + e.getMessage());
        }
    }
}

BufferedWriter Escrever Arquivo

JAVA
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class WriteFile {
    public static void main(String[] args) {
        // Sobrescrever
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
            writer.write("Olá, Mundo!");
            writer.newLine();
            writer.write("Operações com arquivos Java");
            System.out.println("Escrita bem-sucedida");
        } catch (IOException e) {
            System.out.println("Falha na escrita: " + e.getMessage());
        }
        
        // Adicionar
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt", true))) {
            writer.write("Conteúdo adicionado");
            writer.newLine();
            System.out.println("Adição bem-sucedida");
        } catch (IOException e) {
            System.out.println("Falha na adição: " + e.getMessage());
        }
    }
}

try-with-resources

Introduzido no Java 7, fecha automaticamente recursos que implementam AutoCloseable.

Sintaxe

JAVA
try (TipoRecurso variavel = new Recurso()) {
    // Usar recurso
} catch (TipoExcecao e) {
    // Tratar exceção
}

Exemplo: Cópia de Arquivo

JAVA
import java.io.*;

public class FileCopy {
    public static void copy(String src, String dest) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(src));
             BufferedWriter writer = new BufferedWriter(new FileWriter(dest))) {
            
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
        }
        System.out.println("Cópia concluída");
    }
    
    public static void main(String[] args) {
        try {
            copy("source.txt", "dest.txt");
        } catch (IOException e) {
            System.out.println("Falha na cópia: " + e.getMessage());
        }
    }
}
▶ Experimente

Ler Todo o Conteúdo

Método 1: Linha por Linha

JAVA
public static String readAll(String filename) throws IOException {
    StringBuilder sb = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
    }
    return sb.toString();
}

Método 2: Classe Utilitária Files (Java 7+)

JAVA
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;

public class FilesDemo {
    public static void main(String[] args) throws IOException {
        // Ler todas as linhas
        List<String> lines = Files.readAllLines(Paths.get("test.txt"));
        lines.forEach(System.out::println);
        
        // Ler como string
        String content = new String(Files.readAllBytes(Paths.get("test.txt")));
        System.out.println(content);
        
        // Escrever arquivo
        Files.write(Paths.get("output.txt"), "Olá".getBytes());
    }
}

Percorrer Arquivos

Listagem Recursiva de Diretórios

JAVA
import java.io.File;

public class ListFiles {
    public static void listFiles(File dir, String indent) {
        File[] files = dir.listFiles();
        if (files == null) return;
        
        for (File file : files) {
            System.out.println(indent + file.getName());
            if (file.isDirectory()) {
                listFiles(file, indent + "  ");
            }
        }
    }
    
    public static void main(String[] args) {
        File dir = new File(".");
        listFiles(dir, "");
    }
}

Filtragem de Arquivos

JAVA
import java.io.File;
import java.io.FilenameFilter;

public class FileFilter {
    public static void main(String[] args) {
        File dir = new File(".");
        
        // Listar apenas arquivos .txt
        String[] txtFiles = dir.list((d, name) -> name.endsWith(".txt"));
        if (txtFiles != null) {
            for (String name : txtFiles) {
                System.out.println(name);
            }
        }
        
        // Listar apenas diretórios
        File[] dirs = dir.listFiles(File::isDirectory);
        if (dirs != null) {
            for (File d : dirs) {
                System.out.println("[DIR] " + d.getName());
            }
        }
    }
}

Serialização

Converter objetos em fluxos de bytes para salvar em arquivos ou transmissão em rede.

Requisitos de Serialização

Exemplo: Serialização

JAVA
import java.io.*;

// Classe serializável
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    private transient String password;  // transient exclui da serialização
    
    public User(String name, int age, String password) {
        this.name = name;
        this.age = age;
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + ", password='" + password + "'}";
    }
}

public class SerializeDemo {
    public static void main(String[] args) {
        // Serializar
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
            User user = new User("Alice", 25, "123456");
            oos.writeObject(user);
            System.out.println("Serialização bem-sucedida");
        } catch (IOException e) {
            System.out.println("Falha na serialização: " + e.getMessage());
        }
        
        // Deserializar
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
            User user = (User) ois.readObject();
            System.out.println("Deserializado: " + user);
            // User{name='Alice', age=25, password='null'} (senha excluída)
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("Falha na deserialização: " + e.getMessage());
        }
    }
}
▶ Experimente

❓ Perguntas Frequentes

P: Qual é a diferença entre caminhos relativos e absolutos? R: Caminhos relativos são relativos ao diretório de trabalho atual. Caminhos absolutos começam do diretório raiz.

P: Por que usar try-with-resources? R: Fecha recursos automaticamente, prevenindo vazamentos de recursos. Mais conciso que finally manual.

P: O que a palavra-chave transient faz? R: Marca campos que não devem participar da serialização.

📖 Resumo

📝 Exercícios

  1. Estatísticas de arquivo: Conte linhas, palavras e caracteres em um arquivo
  2. Cópia de arquivo: Implemente cópia de arquivo com suporte a arquivos grandes
  3. Percorrer diretório: Liste recursivamente todos os arquivos em um diretório, ordenados por tamanho

Próxima Lição

Na próxima lição, aprenderemos sobre Streams e NIO — IO baseado em fluxos do Java.

100%