Write: примеры (JAVA)
write(ByteBuffer src): intОписание методов write в Java
Методы write принадлежат классам OutputStream и Writer и служат для записи данных в поток. Они используются при работе с файлами, сетевыми соединениями, байтовыми и символьными потоками. Методы перегружены для разных типов данных:
- write(int b) – записывает один байт (младшие 8 бит значения int). Возвращаемое значение: void.
- write(byte[] b) – записывает массив байтов целиком. Возвращаемое значение: void.
- write(byte[] b, int off, int len) – записывает подмассив байтов длиной len, начиная с индекса off. Возвращаемое значение: void.
- write(String str) (класс Writer) – записывает строку. Возвращаемое значение: void.
- write(char[] cbuf) (класс Writer) – записывает массив символов. Возвращаемое значение: void.
Все методы могут выбросить исключение IOException при ошибках ввода-вывода. Методы работают синхронно и не гарантируют атомарность записи для больших данных без дополнительной синхронизации.
Примеры использования write
Пример 1: запись одного байта в файл через FileOutputStream.
try (FileOutputStream fos = new FileOutputStream("output.bin")) {
fos.write(65); // запись символа 'A' (код 65)
} catch (IOException e) { e.printStackTrace(); }Файл output.bin содержит один байт 0x41.
Пример 2: запись массива байтов.
byte[] data = {72, 101, 108, 108, 111}; // "Hello"
try (FileOutputStream fos = new FileOutputStream("hello.bin")) {
fos.write(data);
}Файл hello.bin содержит 5 байт: 48 65 6C 6C 6F.
Пример 3: запись части массива.
byte[] data = {0, 1, 2, 3, 4, 5};
try (FileOutputStream fos = new FileOutputStream("partial.bin")) {
fos.write(data, 2, 3); // запись байтов 2,3,4
}Файл partial.bin содержит 3 байта: 02 03 04.
Пример 4: запись строки через FileWriter.
try (FileWriter fw = new FileWriter("text.txt")) {
fw.write("Привет, мир!");
} catch (IOException e) { e.printStackTrace(); }Файл text.txt содержит строку "Привет, мир!" в кодировке по умолчанию.
Альтернативные методы в Java
В Java существует несколько альтернатив для записи данных:
- BufferedOutputStream.write() – буферизированная запись, уменьшает количество системных вызовов. Предпочтительнее при записи больших объёмов данных.
- PrintWriter.write() / print() / println() – удобен для форматированного вывода текста, автоматически вызывает flush при необходимости.
- Files.write() (NIO, java.nio.file.Files) – запись массива байтов или строки в файл одной строкой кода, с опциями открытия. Подходит для простых задач.
- OutputStreamWriter – мост между символьными и байтовыми потоками, позволяет указать кодировку.
Выбор метода зависит от требуемой буферизации, форматирования и типа данных.
Аналоги в других языках
PHP: fwrite($handle, $string) – записывает строку в файл. Пример:
$fp = fopen('file.txt', 'w');
fwrite($fp, 'Hello');
fclose($fp);Файл содержит 'Hello'.
JavaScript (Node.js): fs.writeFileSync(path, data) – синхронная запись. Пример:
const fs = require('fs');
fs.writeFileSync('file.txt', 'Hello');Файл содержит 'Hello'.
Python: file.write(str) – метод объекта файла. Пример:
with open('file.txt', 'w') as f:
f.write('Hello')Файл содержит 'Hello'.
C#: Stream.Write(byte[], int, int) – аналогичен Java. Пример:
using (var fs = new FileStream("file.bin", FileMode.Create))
{
byte[] data = { 72, 101 };
fs.Write(data, 0, data.Length);
}Файл содержит 2 байта.
Go: file.Write(data []byte) – метод интерфейса io.Writer. Пример:
f, _ := os.Create("file.txt")
f.Write([]byte("Hello"))
f.Close()Файл содержит 'Hello'.
Kotlin: File.writeText(text) – расширение для простой записи строки. Пример:
File("file.txt").writeText("Hello")Файл содержит 'Hello'.
Отличие от Java: в других языках часто есть встроенные функции для записи целой строки или байтового массива без явного управления потоком (например, Python with, Kotlin writeText). В Java требуется явное создание потока и закрытие через try-with-resources.
Типичные ошибки при использовании write
- IOException при отсутствии прав доступа к файлу или при попытке записи в закрытый поток. Пример:
FileOutputStream fos = new FileOutputStream("/root/file.txt"); // может выбросить FileNotFoundException
fos.write(10); // если файл не открыт – IOExceptionИсключение: java.io.FileNotFoundException (если нет прав).
- Неполная запись – метод write не гарантирует запись всех байтов за один вызов (хотя в большинстве реализаций это так). Для гарантии используют цикл или BufferedOutputStream.
- Забытый flush или close – данные могут остаться в буфере и не попасть в файл. Рекомендуется try-with-resources.
- Ошибка кодировки – при использовании FileWriter без указания кодировки могут возникнуть проблемы с нелатинскими символами. Лучше использовать OutputStreamWriter с указанием Charset.
- NullPointerException – передача null в качестве массива или строки.
Изменения в последних версиях Java
- Java 7: введён try-with-resources, упростивший автоматическое закрытие потоков.
- Java 11: добавлены методы Files.writeString() и Files.readString() для простой записи/чтения строк в файл.
- Java 8: улучшена производительность буферизированных потоков.
- В Java 9+ изменений в базовых методах write не вносилось, но появились возможности в NIO (например, FileChannel.write).
Расширенные примеры использования write
Пример A: запись с буферизацией и указанием кодировки
try (OutputStreamWriter osw = new OutputStreamWriter(
new BufferedOutputStream(new FileOutputStream("encoded.txt")),
StandardCharsets.UTF_8)) {
osw.write("Текст в UTF-8");
} catch (IOException e) { e.printStackTrace(); }Файл encoded.txt содержит текст в кодировке UTF-8.
Пример B: запись в сокет
try (Socket socket = new Socket("example.com", 80);
OutputStream out = socket.getOutputStream()) {
String request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
out.write(request.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) { e.printStackTrace(); }Отправляет HTTP-запрос на сервер.
Пример C: использование NIO Files.write для записи списка строк
List lines = List.of("Строка 1", "Строка 2");
Path path = Paths.get("lines.txt");
try {
Files.write(path, lines, StandardCharsets.UTF_8);
} catch (IOException e) { e.printStackTrace(); } Файл lines.txt содержит две строки, разделённые переводом строки.
Пример D: многопоточная запись в один файл с синхронизацией
public class SafeWrite {
private static final Object lock = new Object();
public static void writeToFile(byte[] data) {
synchronized (lock) {
try (FileOutputStream fos = new FileOutputStream("shared.bin", true)) {
fos.write(data);
} catch (IOException e) { e.printStackTrace(); }
}
}
}Потоки безопасно дописывают данные в конец файла.
Пример E: запись с проверкой количества записанных байтов
byte[] largeData = new byte[1024 * 1024]; // 1 МБ
int totalWritten = 0;
try (FileOutputStream fos = new FileOutputStream("large.bin")) {
while (totalWritten < largeData.length) {
int written = fos.write(largeData, totalWritten,
Math.min(4096, largeData.length - totalWritten));
totalWritten += written;
}
} catch (IOException e) { e.printStackTrace(); }Данные записаны частями по 4 КБ, totalWritten == largeData.length.