JavaRush /Java блог /Random UA /Кава-брейк #229. Як працювати з файлами та Input/Output в...

Кава-брейк #229. Як працювати з файлами та Input/Output в Java. Службові методи класу Objects

Стаття з групи Random UA

Як працювати з файлуми та Input/Output в Java

Джерело: Medium Цей посібник пояснює, як створювати, читати, записувати та видаляти файли в Java. Ви також дізнаєтеся, як працюють класи File , InputStream та OutputStream . Кава-брейк #229.  Як працювати з файлуми та Input/Output в Java.  Службові методи класу Objects - 1

Вступ

У Java файли представлені класом File . Клас File надає методи для створення, читання, запису та видалення файлів. Input/output (I/O, введення/виведення) — це процес передачі даних між програмою та зовнішнім джерелом, таким як файл, мережний сокет або консоль. Java надає безліч класів для введення/виведення, включаючи класи InputStream та OutputStream .

Створення файлів

Для створення файлу можна використовувати метод File.createNewFile() . Він створить новий файл, якщо файл з такою назвою ще не існує. Якщо такий файл вже є, то метод createNewFile() видасть виняток IOException . Ось приклад того, як створити новий файл з ім'ям myfile.txt у поточному каталозі:
File myFile = new File("myfile.txt");
myFile.createNewFile();

Читання файлів

Щоб прочитати файл у Java, можна використовувати клас FileInputStream . Він надає методи для читання байтів із файлу. Щоб прочитати вміст файлу, слід використовувати метод read() . Цей метод зчитує один байт із файлу і повертає значення байта. Наприклад, наступний код зчитує вміст файлу myfile.txt і виводить його на консоль:
File myFile = new File("myfile.txt");
FileInputStream inputStream = new FileInputStream(myFile);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
    System.out.print(new String(buffer, 0, bytesRead));
}
inputStream.close();

Записування файлів

Для запису у файл можна використовувати клас FileOutputStream . Він надає методи для запису байтів у файл. Щоб записати вміст рядка у файл, слід використовувати метод write() . Цей метод записує вказану кількість байтів із певного масиву у файл. Ось приклад того, як записується рядок "Hello, world!" у файл myfile.txt :
File myFile = new File("myfile.txt");
FileOutputStream outputStream = new FileOutputStream(myFile);
byte[] buffer = "Hello, world!".getBytes();
outputStream.write(buffer);
outputStream.close();

Видалення файлів

Щоб видалити файл Java, слід використовувати метод File.delete() . Якщо файл, який ви хочете видалити, не існує, то метод delete() поверне false . Перед вами приклад коду, де видаляється файл myfile.txt :
File myFile = new File("myfile.txt");
myFile.delete();

Висновок

У цій публікації ми обговорабо основи роботи з файлуми та I/O Java. Ви дізналися, як створювати, читати, записувати та видаляти файли. Також ви отримали інформацію про клас File і класи InputStream та OutputStream .

Службові методи класу Objects - як з ними працювати

Джерело: Inside Java Завдяки цій публікації ви покращите свої знання про різні методи, представлені в класі Objects . Клас Objects в Java має безліч службових методів, які полегшують виконання різних операцій над об'єктами. У релізах JDK клас Objects зазнав кількох оновлень: були дуже значні оновлення в JDK 8 і 9, і невеликі оновлення в JDK 16 і 19. Давайте розглянемо, як можна використовувати клас Objects .

Порівняння об'єктів

Objects надає кілька варіантів порівняння значень двох об'єктів. Ключовою перевагою використання реалізації Objects є безпека від появи null .

equals()

Нижче наведено приклад порівняння двох записів.
record RaceTime(String runnerName, Duration time) {}

RaceTime nullValue = null;
RaceTime billy =
	new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime copyOfbilly =
	new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime nicolai =
	new RaceTime("Nicolai Parlog", Duration.of(180, ChronoUnit.SECONDS));
nullValue.equals(billy);//NPE
Objects.equals(nullValue, billy);// false
Objects.equals(billy, nicolai);// false
Objects.equals(billy, copyOfbilly);// true

deepEquals()

У класі Objects для порівняння двох масивів можна використовувати deepEquals() . На відміну від звичайного equals() , тут порівнюватимуться значення, що зберігаються в масивах, що має призвести до більш узгоджених результатів. Принципово цей метод проходить через Arrays.deepEquals() .
record RaceTime(String runnerName, Duration time) {}

RaceTime billy =
	new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime nicolai =
	new RaceTime("Nicolai Parlog", Duration.of(180, ChronoUnit.SECONDS));

RaceTime[] raceTimes1 = new RaceTime[] { billy, nicolai };
RaceTime[] raceTimes2 = new RaceTime[] { billy, nicolai };

Objects.equals(raceTimes1, raceTimes2);// false
Objects.deepEquals(raceTimes1, raceTimes2);// true

compare()

Objects також має метод compare() , який може приймати два об'єкти та Comparator<T> . Метод compare() одна із небагатьох null -небезпечних методів в Objects , оскільки він немає прийнятного повернення разі, якщо з аргументів дорівнює null .
record RaceTime(String runnerName, Duration time) {}
class RaceTimeComparator implements Comparator<RaceTime> {
@Override
public int compare(RaceTime o1, RaceTime o2) {
	return o1.time.compareTo(o2.time);
}
}
RaceTime billy =
new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime nicolai =
new RaceTime("Nicolai Parlog", Duration.of(180, ChronoUnit.SECONDS));

Objects.compare(billy, nicolai, new RaceTimeComparator());//-1
Objects.compare(null, nicolai, new RaceTimeComparator());//NPE

String та HashCode

Клас Objects надає методи перетворення об'єкта на значення String і HashCode . Знову ж таки, основною перевагою цих методів є їх безпека від появи null .

Перетворення на String

Одним із найцікавіших методів є toString(obj, nullDefault) , який надає значення за умовчанням (default value) у разі виникнення помилки. Мається на увазі, що toIdentityString(obj) повертає toString() і hashCode() переданих об'єктів, начебто жодного з цих методів не було перезаписано.
record RaceTime(String runnerName, Duration time) {}

RaceTime nullValue = null;
RaceTime billy =
	new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime nicolai =
	new RaceTime("Nicolai Parlog", Duration.of(180, ChronoUnit.SECONDS));

Objects.toString(billy);//RaceTime[runnerName=Billy Korando, time=PT1M30S]
Objects.toString(nullValue);//null
Objects.toString(nullValue, "Did not finish");//Did not finish
Objects.toIdentityString(billy);//ObjectsExamples$1RaceTime@251a69d7

Перетворення на HashCode

Objects також надає методи для перетворення об'єкта на його значення хеш-коду.
record RaceTime(String runnerName, Duration time) {}

RaceTime nullValue = null;
RaceTime billy =
	new RaceTime("Billy Korando", Duration.of(90, ChronoUnit.SECONDS));
RaceTime nicolai =
	new RaceTime("Nicolai Parlog", Duration.of(180, ChronoUnit.SECONDS));

Objects.hashCode(nullValue);//0
Objects.hashCode(billy);//[HashValue]
Objects.hash(billy, nicolai);//[HashValue]

Перевірка на null

Клас Objects надає кілька методів для перевірки та обробки null .

Викидання виключення NullPointException на null

Метод requireNonNull(obj) видасть помилку NullPointException , якщо передане значення дорівнює null .
record RaceTime(String runnerName, Duration time) {
	RaceTime{
		runnerName = Objects.requireNonNull(runnerName);
		time = Objects.requireNonNull(time);
	}
}

Викидання NullPointException на null із повідомленням для користувача

Метод requireNonNull(obj, String) видасть помилку NullPointException з повідомленням користувача, якщо передане значення дорівнює null .
record RaceTime(String runnerName, Duration time) {
	RaceTime{
		runnerName = Objects.requireNonNull(runnerName, "runner name required!");
		time = Objects.requireNonNull(time, "race time required!");
	}
}

Повернення дефолтного значення для null

Метод requireNonNullElse(obj, defaultValue) поверне передане defaultValue якщо obj є null .
record RaceTime(String runnerName, Duration time) {
	RaceTime{
		runnerName = Objects.requireNonNullElse(runnerName, "John Smith");
		time = Objects.requireNonNullElse(time, Duration.ZERO);
	}
}

Використання постачальників (Suppliers)

Клас Objects також надає методи requireNonNull(obj, Supplier<String>) та T requireNonNullElseGet(T, Supplier<T>) , які можуть використовуватися для надання повідомлення або значення за промовчанням. Їх слід використовувати лише в тому випадку, якщо створення повідомлення або значення за промовчанням може вплинути на продуктивність.
record RaceTime(String runnerName, Duration time) {
static Supplier<String> noNameMsgSupplier = () -> "runner name required!";
static Supplier<String> noTimeMsgSupplier = () -> "race time required!";
	RaceTime{
		runnerName = Objects.requireNonNull(runnerName, noNameMsgSupplier);
		time = Objects.requireNonNull(time, noTimeMsgSupplier);
	}
}
record RaceTime(String runnerName, Duration time) {
static Supplier<String> noNameValueSupplier = () -> "John Smith";
static Supplier<Duration> noTimeValueSupplier = () -> Duration.ZERO;
	RaceTime{
		runnerName = Objects.requireNonNullElseGet(runnerName, noNameValueSupplier);
		time = Objects.requireNonNullElseGet(time, noTimeValueSupplier);
	}
}

Предикативна перевірка null

Objects забезпечує перевірку null для використання в предикатах, хоч її можна використовувати і в інших сценаріях.
record RaceTime(String runnerName, Duration time) {}

RaceTime nullValue = null;
Objects.nonNull(nullValue);//false
Objects.isNull(nullValue);//true

Перевірка індексу

І нарешті, клас Objects надає кілька опцій для перевірки позиції індексу при обході File , String , Collection або схожого об'єкта. Деякі з цих методів нещодавно були додані до JDK 16.
int checkIndex(int index, int length)

int checkFromToIndex(int fromIndex, int toIndex, int length)

int checkFromIndexSize(int fromIndex, int size, int length)

long checkIndex(long index, long length)

long checkFromToIndex(long fromIndex, long toIndex, long length)

long checkFromIndexSize(long fromIndex, long size, long length)
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ