CreateNewFile: примеры (JAVA)
createNewFile: booleanОписание метода createNewFile
Метод createNewFile определяется в классе java.io.File и служит для создания нового пустого файла в файловой системе. Подписка метода в классе File выглядит как:
public boolean createNewFile() throws java.io.IOException
Ключевые моменты поведения метода:
- Метод пытается создать новый пустой файл с путём, задаваемым объектом
File. Если файл успешно создан, возвращаетсяtrue. - Если файл уже существует, метод не изменяет его содержимое и возвращает
false. - При возникновении ошибок ввода-вывода (например, отсутствует доступ к диску, отсутствует родительская директория, конфликт с именем и т. п.) бросается
IOException. - Если активен
SecurityManagerи доступ к созданию файла запрещён, бросаетсяSecurityException. - Атомарность: реализация методa в JVM обычно использует атомарную операцию файловой системы для создания нового файла, поэтому вызов сам по себе защищён от простой гонки «проверил-then-создал». Однако проверки отдельно методом
exists()и последующийcreateNewFile()могут иметь состояние гонки.
Аргументы и возвращаемые значения:
- Аргументы: у самого метода аргументов нет. Путь к файлу определяется экземпляром
File, созданным ранее, напримерnew File("path/to/file.txt"). Следует учитывать, что передачаnullв конструкторFileвызоветNullPointerException. - Возвращаемое значение:
boolean-true, если файл был создан;false, если файл уже существовал. - Исключения:
IOExceptionпри ошибках ввода-вывода,SecurityExceptionпри отказе SecurityManager.
Ограничения и замечания:
- Если родительская директория не существует, метод выдаст
IOException. Рекомендуется предварительно создавать директории черезFile.mkdirs()илиFiles.createDirectories(Path). - Метод не устанавливает специальные атрибуты файла при создании; для управления правами и атрибутами применяются API из
java.nio.file. - Для атомарного создания и одновременной записи в файл можно использовать
Files.newByteChannelилиFiles.createFileс опциями.
Краткие примеры использования
1) Создание нового файла и обработка результата
import java.io.File;
import java.io.IOException;
public class Example1 {
public static void main(String[] args) {
File f = new File("example1.txt");
try {
boolean created = f.createNewFile();
System.out.println("created = " + created);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Возможный вывод: created = true // при повторном запуске: created = false
2) Попытка создания файла при отсутствии родительской папки
import java.io.File;
import java.io.IOException;
public class Example2 {
public static void main(String[] args) {
File f = new File("no/such/dir/file.txt");
try {
boolean created = f.createNewFile();
System.out.println(created);
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
}
}
}
IOException: No such file or directory
3) Использование NIO для создания файла (более современный вариант)
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class Example3 {
public static void main(String[] args) {
Path p = Paths.get("example3.txt");
try {
Path created = Files.createFile(p);
System.out.println("created: " + created);
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
}
}
}
// Возможный вывод при первом запуске: created: example3.txt // при повторном запуске: IOException: File already exists: example3.txt
Альтернативные API в Java
Несколько похожих или дополняющих методов и классов:
- java.nio.file.Files.createFile(Path) - создаёт файл через NIO API и возвращает Path, при существующем файле бросает IOException. Предпочтительнее при работе с кодировками путей, атрибутами и при необходимости часто использовать современные возможности NIO.
- Files.newByteChannel(Path, OpenOption...) с опцией
StandardOpenOption.CREATE_NEW- создаёт файл и сразу открывает канал для записи; полезно для атомарной записи содержимого при создании. - File.createTempFile - создание временных файлов с уникальными именами; удобнее для временных данных и тестов.
- FileOutputStream или RandomAccessFile с режимами создания - используются для немедленной записи или перезаписи; их поведение по отношению к существованию файла зависит от выбранного режима.
Выбор между этими вариантами зависит от требований: если нужна простая проверка и создание - подходит createNewFile(). Если необходима работа с атрибутами, поддержка атомарных операций записи, или работа с Path - предпочтительнее NIO (Files).
Аналоги в других языках и отличия
Краткие примеры для популярных языков и отличие от Java:
PHP (функция touch)
// PHP
$ok = touch('file_php.txt');
var_dump($ok);
// bool(true) - если файл создан или обновлён timestamp // Примечание: touch не выдаёт ошибку при существовании, просто обновляет время.
Node.js (флаг 'wx' или флаг 'x' в fs.promises.open)
// Node.js (CommonJS)
const fs = require('fs');
fs.open('file_node.txt', 'wx', (err, fd) => {
if (err) {
console.error('err', err.code);
return;
}
fs.close(fd, () => {});
});
// При существующем файле err.code = 'EEXIST' // При успешном создании - файл создан и дескриптор возвращён.
Python (модуль pathlib, режим 'x')
# Python
from pathlib import Path
p = Path('file_py.txt')
try:
p.write_text('') # перезапишет
except Exception:
pass
# эксклюзивное создание
try:
with open('file_py_x.txt', 'x') as f:
pass
print('created')
except FileExistsError:
print('exists')
// 'created' при новом файле, при существующем бросается FileExistsError
C# (System.IO)
// C#
using System.IO;
// Создание или перезапись
using (var s = File.Create("file_cs.txt")) { }
// Эксклюзивное создание с проверкой
if (!File.Exists("file_cs.txt"))
File.Create("file_cs.txt");
// File.Create перезаписывает файл. Для поведения "fail if exists" нужно использовать FileStream с FileMode.CreateNew.
Go (os.OpenFile с флагами)
// Go
package main
import (
"os"
"fmt"
)
func main() {
f, err := os.OpenFile("file_go.txt", os.O_CREATE|os.O_EXCL, 0644)
if err != nil {
fmt.Println("err=", err)
return
}
f.Close()
fmt.Println("created")
}
// При существующем файле будет ошибка, например "file exists"
Kotlin
// Kotlin использует java.io.File
import java.io.File
fun main() {
val f = File("file_kotlin.txt")
println(f.createNewFile())
}
// true при создании, false если файл уже существует
SQL (пример MySQL) - создание файлов через SELECT INTO OUTFILE
-- MySQL
SELECT 'data' INTO OUTFILE '/tmp/outfile.txt';
-- Файл будет создан на сервере, но требуется привилегия FILE. Поведение сильно отличается от локального API языка.
Отличия: в большинстве языков есть режимы открытия файлов, дающие поведение «создать и fail, если существует» (Python 'x', Node.js 'wx', Go O_EXCL). Java предлагает похожую семантику через createNewFile() и NIO опции CREATE_NEW. Нативные методы в других языках часто возвращают ошибку при существующем файле, тогда как Java-метод возвращает false.
Типичные ошибки и примеры
1) Отсутствие родительской директории
import java.io.File;
import java.io.IOException;
public class Err1 {
public static void main(String[] args) {
File f = new File("missing_dir/file.txt");
try {
f.createNewFile();
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
}
}
}
Ошибка: No such file or directory
Решение: предварительно создать директорию
new File("missing_dir").mkdirs();
// затем f.createNewFile();
2) Неправильная обработка существования файла (гонка)
// Плохо - возможна гонка
File f = new File("race.txt");
if (!f.exists()) {
f.createNewFile();
}
// Между exists() и createNewFile() другой поток может создать файл.
// Рекомендация: полагаться на атомарность createNewFile(), не на exists()
3) SecurityException при ограниченном доступе
// при активном SecurityManager вызов может бросить SecurityException
try {
new File("/root/protected.txt").createNewFile();
} catch (SecurityException se) {
System.out.println("Доступ запрещён: " + se.getMessage());
}
Доступ запрещён: access denied (пример)
4) NullPointerException при передаче null в конструктор File
File f = new File(null); // бросит NullPointerException
Exception in thread "main" java.lang.NullPointerException
5) Неправильное ожидание побочных эффектов (например, создание родительских директорий)
// Ожидание, что createNewFile создаст директории - неверно
File f = new File("a/b/c.txt");
f.createNewFile(); // IOException если a/b не существует
IOException: No such file or directory
Изменения и история
Краткая история метода и связанных API:
- File.createNewFile() присутствует с ранних версий Java (включая JDK 1.0) и существенно не менялся.
- С появлением NIO.2 в Java 7 введён пакет
java.nio.fileи методыFiles.createFile,Files.createTempFileи опции открытия, которые предоставляют более гибкие и мощные средства для работы с файлами и атрибутами. - Непосредственно метод
createNewFile()изменений API в последних версиях Java не претерпел, но приоритет при реализации новых приложений обычно отдают NIO.
Расширенные и редкие сценарии использования
1) Создание файла с последующей атомарной записью через NIO
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.IOException;
public class Adv1 {
public static void main(String[] args) throws IOException {
Path p = Paths.get("adv1.txt");
byte[] data = "Hello".getBytes();
// CREATE_NEW гарантирует, что создание файла и открытие для записи будут атомарными
Files.write(p, data, StandardOpenOption.CREATE_NEW);
System.out.println("written");
}
}
written // При повторном запуске будет IOException: File already exists
2) Создание файла с POSIX-правами (только для POSIX-систем)
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.attribute.FileAttribute;
import java.io.IOException;
public class Adv2 {
public static void main(String[] args) throws IOException {
Path p = Paths.get("adv2.txt");
FileAttribute<?> perms = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-r-----"));
Files.createFile(p, perms);
System.out.println("created with posix perms");
}
}
created with posix perms
3) Создание файла в многопоточном окружении - избегание гонки
// Лучший подход - полагаться на атомарный createNewFile, а не на exists()
File f = new File("mt.txt");
try {
boolean created = f.createNewFile();
if (created) {
// безопасно выполнять инициализацию файла
} else {
// файл уже существует
}
} catch (IOException e) {
// обработка ошибки
}
// При параллельных запусках ровно один вызов получит created = true, остальные false
4) Создание временного файла в указанной директории
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class Adv3 {
public static void main(String[] args) throws IOException {
Path dir = Paths.get(System.getProperty("java.io.tmpdir"));
Path temp = Files.createTempFile(dir, "prefix_", ".tmp");
System.out.println("temp: " + temp);
}
}
temp: /tmp/prefix_1234567890.tmp
5) Создание файла с использованием FileChannel и lock для эксклюзивного доступа
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.io.IOException;
public class Adv4 {
public static void main(String[] args) throws IOException {
try (RandomAccessFile raf = new RandomAccessFile("adv4.txt", "rw");
FileChannel ch = raf.getChannel()) {
FileLock lock = ch.tryLock();
if (lock != null) {
try {
// инициализация файла под блокировкой
} finally {
lock.release();
}
}
}
}
}
// Позволяет синхронизировать доступ между процессами, но не заменяет атомарное создание.
6) Комбинация создания родительских директорий и последующего создания файла
import java.io.File;
import java.io.IOException;
File f = new File("a/b/c.txt");
if (f.getParentFile() != null) {
f.getParentFile().mkdirs();
}
boolean created = f.createNewFile();
System.out.println(created);
true // при успешном создании
Пояснения: примеры показывают сочетание старого IO и NIO подходов, управление правами, атомарную запись и защиту в многопоточном/мультипроцессном окружении.