← Назад к вопросам

Дополняет ли файл запись через FileOutputStream

1.0 Junior🔥 141 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Дополняет ли FileOutputStream запись в файл

Короткий ответ: ПО УМОЛЧАНИЮ НЕТ, перезаписывает

FileOutputStream по умолчанию перезаписывает (truncate) содержимое файла, но это поведение можно изменить, передав флаг append=true в конструктор.

Поведение FileOutputStream

1. По умолчанию: ПЕРЕЗАПИСЬ (truncate)

// По умолчанию truncates файл (перезаписывает)
FileOutputStream fos = new FileOutputStream("file.txt");
fos.write("Hello".getBytes());
fos.close();

// Результат файла: "Hello" (4 байта)

// Второй запуск:
FileOutputStream fos2 = new FileOutputStream("file.txt");
fos2.write("World".getBytes());  // Файл пересоздан
fos2.close();

// Результат файла: "World" (5 байт)
// Старое содержимое "Hello" удалено!

2. Дополнение: APPEND mode

// Второй параметр true = режим дополнения
FileOutputStream fos = new FileOutputStream("file.txt", true);
fos.write("Hello".getBytes());
fos.close();

System.out.println("Файл содержит: Hello");

// Второй запуск в режиме append
FileOutputStream fos2 = new FileOutputStream("file.txt", true);
fos2.write(" World".getBytes());  // Добавляется в конец
fos2.close();

System.out.println("Файл содержит: Hello World");

Конструкторы FileOutputStream

// Конструктор 1: Перезапись (truncate)
// public FileOutputStream(String name) throws FileNotFoundException
FileOutputStream fos1 = new FileOutputStream("file.txt");

// Конструктор 2: С флагом append
// public FileOutputStream(String name, boolean append) throws FileNotFoundException
FileOutputStream fos2 = new FileOutputStream("file.txt", false);  // Перезапись
FileOutputStream fos3 = new FileOutputStream("file.txt", true);   // Дополнение

// Конструктор 3: Через File объект
// public FileOutputStream(File file, boolean append) throws FileNotFoundException
File file = new File("file.txt");
FileOutputStream fos4 = new FileOutputStream(file, true);  // Дополнение

Практические примеры

Пример 1: Перезапись файла

import java.io.FileOutputStream;
import java.io.IOException;

public class FileWriteExample {
    public static void main(String[] args) throws IOException {
        String filename = "log.txt";
        String message = "Application started\n";
        
        // ПЕРЕЗАПИСЬ: удаляет старое содержимое
        FileOutputStream fos = new FileOutputStream(filename, false);
        fos.write(message.getBytes());
        fos.close();
        
        System.out.println("Файл перезаписан");
        
        // Если файл уже существовал, содержимое удалено!
    }
}

Пример 2: Дополнение файла (log-файл)

import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LoggerExample {
    private String logFile = "app.log";
    
    public void log(String message) throws IOException {
        String timestamp = LocalDateTime.now()
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        
        String logEntry = "[" + timestamp + "] " + message + "\n";
        
        // ДОПОЛНЕНИЕ: добавляет в конец файла
        FileOutputStream fos = new FileOutputStream(logFile, true);
        fos.write(logEntry.getBytes());
        fos.close();
    }
    
    public static void main(String[] args) throws IOException {
        LoggerExample logger = new LoggerExample();
        
        logger.log("Application started");
        logger.log("Processing request");
        logger.log("Request completed");
        
        // Все логи дополнены в один файл
    }
}

Пример 3: Опасный сценарий (кейс без append)

import java.io.FileOutputStream;
import java.io.IOException;

public class DangerousExample {
    public static void main(String[] args) throws IOException {
        String dataFile = "important_data.txt";
        
        // Первый запуск: записываем важные данные
        FileOutputStream fos = new FileOutputStream(dataFile, false);
        fos.write("Важные данные: список пользователей\n".getBytes());
        fos.close();
        
        System.out.println("Данные сохранены");
        
        // ... программа продолжает работу ...
        
        // Позже: забыли про флаг append
        FileOutputStream fos2 = new FileOutputStream(dataFile);  // ОШИБКА!
        fos2.write("Новая запись\n".getBytes());
        fos2.close();
        
        // РЕЗУЛЬТАТ: все важные данные удалены!
        // Файл содержит только: "Новая запись"
    }
}

Сравнение с другими способами записи

FileOutputStream (low-level)

// Перезапись
FileOutputStream fos = new FileOutputStream("file.txt");  // truncate
fos.write(data);
fos.close();

// Дополнение
FileOutputStream fos = new FileOutputStream("file.txt", true);  // append
fos.write(data);
fos.close();

FileWriter (более удобно для текста)

// Перезапись
FileWriter fw = new FileWriter("file.txt");  // truncate
fw.write("text");
fw.close();

// Дополнение
FileWriter fw = new FileWriter("file.txt", true);  // append
fw.write("text");
fw.close();

Files.write (Java NIO, удобно)

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

// Перезапись (по умолчанию CREATE, WRITE, TRUNCATE_EXISTING)
Files.write(Paths.get("file.txt"), "Hello".getBytes());

// Дополнение (явно указываем APPEND)
Files.write(
    Paths.get("file.txt"),
    "World".getBytes(),
    StandardOpenOption.CREATE,
    StandardOpenOption.APPEND
);

BufferedOutputStream + append

FileOutputStream fos = new FileOutputStream("file.txt", true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(data);
bos.flush();
bos.close();

Важные детали

1. Файл должен существовать?

// Если файл НЕ существует, он будет создан (и в truncate, и в append mode)
FileOutputStream fos = new FileOutputStream("new_file.txt", false);
fos.write("Hello".getBytes());
fos.close();  // Файл создан

// Если файл существует:
// - append=false: содержимое перезаписывается
// - append=true: новые данные добавляются в конец

2. Файловый указатель (File Pointer)

// ПЕРЕЗАПИСЬ (append=false)
// File pointer установлен в начало (0)
FileOutputStream fos1 = new FileOutputStream("file.txt", false);
// Файл: [_ _ _ _ _]  <- pointer здесь

// ДОПОЛНЕНИЕ (append=true)
// File pointer установлен в конец файла
FileOutputStream fos2 = new FileOutputStream("file.txt", true);
// Файл: [H e l l o]_  <- pointer в конце

3. Обработка исключений

String filename = "output.txt";

try (FileOutputStream fos = new FileOutputStream(filename, true)) {
    fos.write("Data\n".getBytes());
    fos.flush();  // Убедиться, что данные записаны
} catch (IOException e) {
    System.err.println("Ошибка записи файла: " + e.getMessage());
}
// try-with-resources автоматически закроет fos

Best Practices

  1. Явно указывайте флаг append:

    // ПЛОХО: непонятно какое поведение
    new FileOutputStream(filename);
    
    // ХОРОШО: явный флаг
    new FileOutputStream(filename, true);   // дополнение
    new FileOutputStream(filename, false);  // перезапись
    
  2. Используйте try-with-resources:

    try (FileOutputStream fos = new FileOutputStream(filename, true)) {
        fos.write(data);
    } catch (IOException e) {
        // обработка
    }
    
  3. Для текстовых файлов предпочитайте FileWriter:

    try (FileWriter fw = new FileWriter(filename, true)) {
        fw.write("text");
    }
    
  4. Для современного кода используйте Files API:

    Files.write(
        Paths.get(filename),
        content.getBytes(),
        StandardOpenOption.CREATE,
        StandardOpenOption.APPEND
    );
    

Вывод

FileOutputStream по умолчанию ПЕРЕЗАПИСЫВАЕТ файл (truncate), стирая его содержимое. Чтобы дополнять файл, необходимо явно передать второй параметр true при создании объекта:

FileOutputStream fos = new FileOutputStream(filename, true);  // true = append/дополнение

Без этого флага все предыдущие данные в файле будут удалены. Это частая ошибка при работе с логами и конфигурационными файлами.

Дополняет ли файл запись через FileOutputStream | PrepBro