Java for Beginner
871 subscribers
1.01K photos
275 videos
14 files
1.68K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Изменение времени модификации: Files.setLastModifiedTime()

Метод Files.setLastModifiedTime(Path path, FileTime time) устанавливает время последней модификации файла. Это полезно для инструментов, которые копируют файлы и хотят сохранить оригинальные временные метки, или для тестов, которым нужно симулировать старый файл.
import java.nio.file.*;
import java.nio.file.attribute.FileTime;
import java.io.IOException;
import java.time.Instant;

public class ModificationTimeSetter {

public void touchFile(Path path) throws IOException {
// "Touch" — обновить время модификации до текущего момента
FileTime now = FileTime.from(Instant.now());
Files.setLastModifiedTime(path, now);
}

public void setSpecificTime(Path path, Instant instant) throws IOException {
FileTime fileTime = FileTime.from(instant);
Files.setLastModifiedTime(path, fileTime);
}

public void copyTimestamps(Path source, Path target) throws IOException {
// Копируем временные метки с источника на назначение
BasicFileAttributes sourceAttrs = Files.readAttributes(
source, BasicFileAttributes.class
);

Files.setLastModifiedTime(target, sourceAttrs.lastModifiedTime());

// Время создания и доступа устанавливаются через setAttribute
Files.setAttribute(target, "basic:creationTime", sourceAttrs.creationTime());
Files.setAttribute(target, "basic:lastAccessTime", sourceAttrs.lastAccessTime());
}
}


FileTime
— неизменяемый класс, поэтому его экземпляры безопасно передавать между потоками.

Он предоставляет несколько фабричных методов:
FileTime.from(Instant instant) — из объекта Instant (точка на временной шкале UTC).
FileTime.fromMillis(long millis) — из миллисекунд с эпохи Unix (1 января 1970).
FileTime.from(long value, TimeUnit unit) — из произвольной единицы времени.

Эпоха Unix (Unix epoch) — это момент времени 00:00:00 UTC 1 января 1970 года. Время в Unix-системах традиционно отсчитывается от этой точки в секундах или миллисекундах.


Универсальный метод: Files.setAttribute()

Метод Files.setAttribute(Path path, String attribute, Object value, LinkOption... options) позволяет установить любой атрибут по его строковому имени. Это полезно, когда вы работаете с атрибутами динамически или пишете универсальный код, не привязанный к конкретному типу файловой системы.


Синтаксис имени атрибута

Имя атрибута имеет формат viewName:attributeName. Если viewName опущен, используется "basic".
// Установка времени модификации через универсальный метод
Files.setAttribute(path, "basic:lastModifiedTime", FileTime.from(Instant.now()));

// Установка POSIX-прав
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
Files.setAttribute(path, "posix:permissions", perms);

// Установка владельца (только Unix с соответствующими правами)
UserPrincipalLookupService lookup = FileSystems.getDefault().getUserPrincipalLookupService();
UserPrincipal newOwner = lookup.lookupPrincipalByName("admin");
Files.setAttribute(path, "posix:owner", newOwner);


UserPrincipal
— это интерфейс в NIO.2, представляющий пользователя или группу в файловой системе. UserPrincipalLookupService — сервис для поиска пользователей по имени.

Метод setAttribute() использует рефлексию и динамическую диспетчеризацию: он парсит строку имени, находит соответствующее FileAttributeView, вызывает его метод записи. Это менее эффективно, чем прямой вызов специализированного метода (например, Files.setPosixFilePermissions()), но предоставляет гибкость при работе с неизвестными заранее типами атрибутов.

Рефлексия (reflection) — это механизм Java, позволяющий программе исследовать и модифицировать структуру и поведение объектов во время выполнения: получать классы, методы, поля, вызывать методы по имени.
Работа с правами доступа POSIX: Files.setPosixFilePermissions()


На Unix-подобных системах права доступа к файлам управляются через POSIX-биты. Класс PosixFilePermissions предоставляет удобные методы для работы с ними.
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.Set;

public class PosixPermissionManager {

public void setStrictPermissions(Path path) throws IOException {
// rw------- — только владелец может читать и писать
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
Files.setPosixFilePermissions(path, perms);
}

public void setExecutable(Path path) throws IOException {
// Добавляем право на выполнение для владельца
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(path);
perms.add(PosixFilePermission.OWNER_EXECUTE);
Files.setPosixFilePermissions(path, perms);
}

public void setSharedReadOnly(Path path) throws IOException {
// r--r--r-- — все могут читать, никто не может писать
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("r--r--r--");
Files.setPosixFilePermissions(path, perms);
}

public void copyPermissions(Path source, Path target) throws IOException {
// Копируем POSIX-права с одного файла на другой
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(source);
Files.setPosixFilePermissions(target, perms);
}

public void createWithPermissions(Path path, String permString) throws IOException {
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(permString);
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);

// createFile с FileAttribute устанавливает права атомарно при создании
Files.createFile(path, attr);
}
}


PosixFilePermission
— это enum, определяющий девять возможных битов прав:
Владелец: OWNER_READ, OWNER_WRITE, OWNER_EXECUTE
Группа: GROUP_READ, GROUP_WRITE, GROUP_EXECUTE
Остальные: OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE

Строковое представление "rwxr-xr-x" — это стандартная нотация Unix ls -l, где каждая триада символов описывает права для владельца, группы и остальных. Дефис означает отсутствие права.


#Java #для_новичков #beginner #IO #NIO #Files #BasicFileAttributes
👍4
Пример: установка времени модификации файла в текущий момент
import java.nio.file.*;
import java.nio.file.attribute.FileTime;
import java.io.IOException;
import java.time.Instant;

public class FileToucher {

public void touch(Path path) throws IOException {
if (Files.notExists(path)) {
// Если файла нет — создаём пустой файл
// и время модификации будет равно времени создания (сейчас)
Files.createFile(path);
System.out.println("Файл создан: " + path);
return;
}

// Файл существует — обновляем только время модификации
FileTime now = FileTime.from(Instant.now());
Files.setLastModifiedTime(path, now);

// Проверяем, что установилось
FileTime verify = Files.getLastModifiedTime(path);
if (verify.compareTo(now) >= 0) {
System.out.println("Время модификации обновлено: " + verify);
} else {
throw new IOException("Не удалось обновить время модификации");
}
}

public void touchWithAccessTime(Path path) throws IOException {
// Обновляем и время модификации, и время доступа
FileTime now = FileTime.from(Instant.now());

Files.setAttribute(path, "basic:lastModifiedTime", now);
Files.setAttribute(path, "basic:lastAccessTime", now);

// Проверяем через readAttributes
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("mtime: " + attrs.lastModifiedTime());
System.out.println("atime: " + attrs.lastAccessTime());
}

public static void main(String[] args) {
try {
Path file = Paths.get("/tmp/test_touch.txt");
new FileToucher().touch(file);
} catch (IOException e) {
System.err.println("Ошибка: " + e.getMessage());
}
}
}


Команда touch в Unix работает именно так: если файла нет — создаёт пустой, если есть — обновляет временные метки. Важно, что Files.setLastModifiedTime() не изменяет содержимое файла, только метаданные inode.


Путь байтов в памяти JVM при работе с атрибутами

Чтение атрибутов: путь данных

При вызове Files.readAttributes(path, BasicFileAttributes.class):
Объект Path находится в куче (Heap). JVM извлекает его строковое представление и кодирует в массив байтов пути в нативной памяти через JNI.
Выполняется системный вызов stat() (POSIX) или GetFileAttributesEx() (Windows). Ядро ОС читает inode/MFT-запись и возвращает структуру с метаданными в нативную память ядра.
JNI-код JVM копирует поля структуры из нативной памяти в объекты Java. Создаётся экземпляр внутреннего класса, реализующего BasicFileAttributes (например, UnixFileAttributes в OpenJDK). Этот объект создаётся в Young Generation, в области Eden.
Поля объекта атрибутов содержат примитивы (long для размера, long для наносекунд времени) и объекты FileTime. Каждый вызов creationTime(), lastModifiedTime(), lastAccessTime() возвращает новый объект FileTime или кэшированный экземпляр — это зависит от реализации JVM. В OpenJDK FileTime создаётся лениво при первом вызове геттера и кэшируется в поле объекта атрибутов.
Объект BasicFileAttributes — лёгкий: он содержит несколько long-полей и ссылки на FileTime. Если вы читаете атрибуты в цикле (например, при сканировании директории из 100 000 файлов), каждая итерация создаёт новый объект атрибутов в Eden. Эти объекты становятся мусором сразу после обработки файла, если вы не сохраняете ссылку. Minor GC эффективно собирает их, так как они не переживают цикла.
Если вы сохраняете атрибуты в долгоживущую коллекцию (например, строите карту Map<Path, BasicFileAttributes> для всех файлов проекта), объекты атрибутов переходят в Old Generation через Survivor Space. При большом количестве файлов это может существенно увеличить размер Old Generation и вызвать Major GC (Full GC) раньше, чем ожидалось.

Запись атрибутов: путь данных

При Files.setLastModifiedTime(path, fileTime):
Объект FileTime хранит время как long в наносекундах (или секундах + наносекунды). Он находится в куче. JVM извлекает примитивное значение и передаёт его в нативный код.
Выполняется системный вызов utimensat() (современный POSIX, поддерживает наносекунды) или utime() (устаревший, точность до секунд). На Windows — SetFileTime().
Ядро ОС обновляет соответствующие поля в inode/MFT. Это операция только над метаданными; блоки данных файла не затрагиваются.
Никаких новых объектов в куче JVM не создаётся. Метод возвращает void. Объект FileTime, переданный как параметр, остаётся в куче до тех пор, пока на него есть ссылка. Если это локальная переменная — он собирается при следующей Minor GC.


POSIX-права: путь данных

При Files.setPosixFilePermissions(path, permissions):
Множество Set<PosixFilePermission> — это объект в куче, содержащий ссылки на enum-константы. Enum-константы в Java создаются один раз при загрузке класса и хранятся в Metaspace (вместе с классом PosixFilePermission). Само множество — это объект HashSet или EnumSet в куче.

JVM преобразует множество разрешений в целое число — битовую маску POSIX-прав. Эта маска передаётся в нативный код.

Выполняется системный вызов chmod() (POSIX) или SetFileSecurity() (Windows, если используется ACL-эмуляция). Ядро обновляет биты прав в inode.
Объект Set<PosixFilePermission> становится мусором после выхода из метода, если он не сохранён. Minor GC собирает его. Enum-константы остаются в Metaspace навсегда (до выгрузки класса), так как Metaspace не подлежит обычной сборке мусора в полном смысле — классы выгружаются только при выгрузке ClassLoader'а.

ClassLoader — это компонент JVM, отвечающий за динамическую загрузку классов в память. Каждый загруженный класс хранится в Metaspace и связан с ClassLoader'ом. Когда ClassLoader становится недостижимым для GC, все его классы и связанные с ними структуры Metaspace могут быть освобождены.


Оптимизация: массовое чтение атрибутов и давление на GC

При сканировании больших файловых деревьев частая ошибка — хранение всех атрибутов в памяти:
// Проблемный код: храним все атрибуты в памяти
Map<Path, BasicFileAttributes> cache = new HashMap<>();
Files.walk(root).forEach(p -> {
try {
cache.put(p, Files.readAttributes(p, BasicFileAttributes.class));
} catch (IOException e) { /* ignore */ }
});
// При миллионе файлов cache содержит миллион объектов BasicFileAttributes в Old Generation


Каждый объект BasicFileAttributes в OpenJDK занимает примерно 40–56 байт (зависит от архитектуры и JVM). Для миллиона файлов это 40–56 МБ только на объекты атрибутов, плюс накладные расходы HashMap (примерно в 2 раза больше). Это может привести к Major GC или OOM.

Оптимизированный подход — извлекать только нужные поля и не хранить объекты атрибутов:
// Оптимизированный код: извлекаем только размер и mtime, храним примитивы
Map<Path, Long> sizeCache = new HashMap<>();
Files.walk(root).forEach(p -> {
try {
BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class);
sizeCache.put(p, attrs.size()); // только long, лёгкий объект
} catch (IOException e) { /* ignore */ }
});
// Объект attrs становится мусором сразу после итерации


Ещё лучше — использовать Files.newDirectoryStream() и читать атрибуты порциями, не загружая всё дерево в память:
// Обход с минимальным потреблением памяти
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) {
BasicFileAttributes attrs = Files.readAttributes(entry, BasicFileAttributes.class);
process(entry, attrs.size(), attrs.lastModifiedTime());
// attrs собирается GC сразу после process()
}
}



#Java #для_новичков #beginner #IO #NIO #Files #BasicFileAttributes
👍3
Что выведет код?

import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.io.*;

public class Task170726 {
public static void main(String[] args) throws IOException, InterruptedException {
Path path = Paths.get("test.txt");
Files.write(path, "ABC".getBytes());

BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
long size1 = attrs.size();
long modified1 = attrs.lastModifiedTime().toMillis();

Thread.sleep(2000);
Files.write(path, "ABCDE".getBytes(), StandardOpenOption.TRUNCATE_EXISTING);

long size2 = attrs.size();
long modified2 = attrs.lastModifiedTime().toMillis();

BasicFileAttributes attrsNew = Files.readAttributes(path, BasicFileAttributes.class);
long size3 = attrsNew.size();
long modified3 = attrsNew.lastModifiedTime().toMillis();

System.out.println(size1 + " " + size2 + " " + size3);
System.out.println(modified1 == modified2);
System.out.println(modified1 == modified3);
}
}


#Tasks
👍2
Ребят, есть предложение! 😉

А давайте как в старые-добрые встретимся в воскресение часиков с 16 по мск и посидим, поговорим?

Предлагайте темы и вопросы которые можем обсудить.

Можем просто провести нытинг)

Старичкам канала быть обязательно! 😏

Придёте? 🚘
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👎1🤣1
Что такое StackWalker в Java 9? 🤓

Ответ:

StackWalker (Java 9)
— это эффективный API для обхода стека вызовов.

Предоставляет метод walk(Function<Stream<StackFrame>, T>) для получения стрима кадров стека.

Более производительный, чем Thread.getStackTrace(), так как не создаёт массив всех кадров, а лениво обходит только нужные.

Позволяет фильтровать, пропускать и т.д. Полезен для логирования, отладки, безопасности (проверка, кто вызывает метод). Поддерживает режимы: RETAIN_CLASS_REFERENCE для работы с классами.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 18 июля

ℹ️ Кто родился в этот день

Ро́алд Хо́ффман (англ. Roald Hoffmann; род. 18 июля 1937 года, Золочев, Тарнопольское воеводство, Польша) — американский химик, лауреат Нобелевской премии по химии «за разработку теории протекания химических реакций» совместно с Кэнъити Фукуи.

Ха́ртмут Ми́хель (нем. Hartmut Michel; род. 18 июля 1948 года, Людвигсбург, Германия) — немецкий биохимик, лауреат Нобелевской премии по химии 1988 года за точную структуру бактериального реакционного фотосинтетического центра.


🌐 Знаковые события

1898Пьер и Мария Кюри представили в Парижской Академии доклад об открытии нового химического элемента — полония — второго после урана, обладающего радиоактивностью.

1968 — образована компания «Intel». Её основали Роберт Нойс и Гордон Мур.

1991 — Вышел первый номер компьютерного еженедельника «ComputerWorld — USSR», который известен под названием «Computer Weekly».

2011 — запуск космической обсерватории «Радиоастрон».


#Biography #Birth_Date #Events #18июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Эххххх и правда ведь....)
🤣4
Не оставляем телефон без присмотра....
🤣31
Напоминаю, завтра в 16 по МСК, я дам ссылочку присоединившись по которой, мы сможем посидеть и пообщаться.

Поотвечаю на вопросы, обсудим наболевшее)))

Приходите
🔥7
Скоро релиз))

Если я когда нибудь победю Angular)))

Как вам? (это еще не доработанная версия)
🔥11
История технологии сегодня — 19 июля

ℹ️ Кто родился в этот день

Сэмюэл Кольт (Самуи́л Кольтангл. Samuel Colt; 22 июля 1814Хартфорд — 10 января 1862Хартфорд) — американский оружейник, изобретатель и промышленник, основатель компании Colt’s Patent Fire-Arms Manufacturing Company (сейчас Colt’s Manufacturing Company). Происходил из аристократической и достаточно богатой семьи, но независимо от этого основал компанию сам. Наибольшей известностью пользуется как реформатор револьверного оружия: в 1835 году изобрёл капсульный револьвер, который быстро потеснил другие системы и дал толчок для создания револьверов под унитарный металлический патрон.


🌐 Знаковые события

1927 — В Ленинграде испытан первый отечественный аэроглиссер.


#Biography #Birth_Date #Events #19июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ну как так то...)))
🤓2
Вот такая система оценок будет. 💪

Как вам? ☺️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Please open Telegram to view this post
VIEW IN TELEGRAM
🤓2
Quod licet Iovi, non licet bovi
👍3
История технологии сегодня — 20 июля

ℹ️ Кто родился в этот день

Григо́рий Васи́льевич Кисунько́ (укр. Григорій Васильович Кісунько; 20 июля 1918, Бельманка, Екатеринославская губерния — 11 октября 1998, Москва) — советский учёный в области радиоэлектроники. Один из создателей советской системы противоракетной обороны.

Герд Карл Би́нниг (нем. Gerd Karl Binnig; род. 20 июля 1947) — немецкий физик, в 1986 году совместно с Генрихом Рорером получил Нобелевскую премию по физике за изобретение сканирующего туннельного микроскопа. Разработки Биннига расширили возможности нанотехнологий, позволив не только визуализировать отдельные атомы, но и манипулировать ими.

Гео́ргий Э́рихович Лангема́к (8 (20) июля 1898, Старобельск, Старобельский уезд, Харьковская губерния, Российская империя — 11 января 1938, Москва, РСФСР, СССР) российский и советский учёный, один из пионеров ракетной техники и один из создателей первых реактивных снарядов в СССР. Основоположник исследований по конструированию реактивных снарядов на бездымном порохе, открыл так называемый закон подобия, знание которого позволило определять оптимальную геометрию сопла реактивного двигателя без длительных дорогостоящих экспериментов — аналитическим расчётом. Ввёл в русский язык термин «космонавтика».


🌐 Знаковые события

1807 — Нисефор Ньепс с братом получили патент на один из ранних двигателей внутреннего сгоранияпиреолофор[англ.].

1969 — «Аполлон-11» совершил первую в истории пилотируемую посадку на Луну.


#Biography #Birth_Date #Events #20июля
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Вакансия мечты, не? 🚽
Please open Telegram to view this post
VIEW IN TELEGRAM
1