← Назад к вопросам
Дополняет ли файл запись через 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
-
Явно указывайте флаг append:
// ПЛОХО: непонятно какое поведение new FileOutputStream(filename); // ХОРОШО: явный флаг new FileOutputStream(filename, true); // дополнение new FileOutputStream(filename, false); // перезапись -
Используйте try-with-resources:
try (FileOutputStream fos = new FileOutputStream(filename, true)) { fos.write(data); } catch (IOException e) { // обработка } -
Для текстовых файлов предпочитайте FileWriter:
try (FileWriter fw = new FileWriter(filename, true)) { fw.write("text"); } -
Для современного кода используйте Files API:
Files.write( Paths.get(filename), content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND );
Вывод
FileOutputStream по умолчанию ПЕРЕЗАПИСЫВАЕТ файл (truncate), стирая его содержимое. Чтобы дополнять файл, необходимо явно передать второй параметр true при создании объекта:
FileOutputStream fos = new FileOutputStream(filename, true); // true = append/дополнение
Без этого флага все предыдущие данные в файле будут удалены. Это частая ошибка при работе с логами и конфигурационными файлами.