Введення і виведення інформації - це те, з чим стикається програміст на кожному кроці. Це відноситься як до написання комерційних продуктів, так і до вирішення олімпіадних завдань. Склалося так, що новачкові важко розібратися в тому, як ці дії виполняютя засобами мови Java. В даному тексті я спробую полегшити цю проблему, побіжно розглянувши можливості пакета java.io.
У центрі всього, що пов'язано з введенням / виводом інформації, лежить поняття потоку (stream). Потік - це просто джерело інформації або ж місце, куди інформацію можна направити. Нас цікавить випадок роботи з файлами.
Найпростіший вид потоку - той, який працює з двійковим представеніем інформації, інакше, з байтами. Всі бінарні потоки успадковуються від двох абстрактних класів - InputStream і OutputStream. Нам важливі два нащадка - FileInputStream і FileOutputStream відповідно. Ось шматок тексту програми, яка копіює вміст файлу a.txt в файл b.txt:
Не забувайте закривати потоки методом close (). Ваші дані можуть бути загублені. Обидва класи мають зручними конструкторами від шляху до файлу. Якщо b.txt не існує, то буде створений. Інакше - переписаний. Не забувайте відловлювати виключення (або ж вказувати їх у заголовках методів).
На практиці працювати з двійковим поданням даних при написанні олімпіадних завдань не доводиться. Невеликим кроком вперед послужать FileReader і FileWriter. які дуже схожі на бінарних братів. Для нас відміну тільки в тому, що вони працюють з символами. Нову можливість надають BufferedReader і PrintWriter. які можна розглядати, як обгортки для вже попередньої пари класів. Ця можливість - Прогресивне читання і запис файлу. Наведемо все той же приклад копіювання файлу:
Клас PrintWriter дуже близький до стандартних можливостей мови C. Методи print () і println () визначені для всіх стандартних типів (останній додає новий рядок в кінець виводу), а метод printf () дуже схожий на відповідну процедуру мови C. За подробицями по темі синтаксису рядка форматування звертайтеся на відповідну сторінку допомоги. BufferedReader радує лише наявністю методу readLine ().
Починаючи з версії 1.5. мова нарешті довів переваги ООП з точки зору введення інформації. Це було сязано з появою класу Scanner в пакеті java.util. Для кожного з базових типів (а також класів довгої арифметики) є пара методів: hasNextT () говорить, чи можна далі прочитати елемент типу T. в той час як nextT () цей елемент намагається вважати. Методи hasNext () і next () працюють окремими словами (за подробицями звертайтеся до опису класу). Наступний приклад копіює послідовність 32-бітних чисел, розташованих на початку файлу a.txt в файл b.txt. виписуючи їх через підрядник:
Хоча Scanner і не є потоком, у нього теж обов'язково викликати метод close (). який закриє використовуваний за основне джерело потік. Знавці скажуть, що схожу функціональність надавали, починаючи з першої версії, DataInputStream і DataOutputStream. проте їх можливості біднішими, та й працюють вони не завжди коректно (тому користуватися ними строго не рекомендується).
Залишається лише побажати успіхів і порадити іноді заглядати в документацію вашого улюбленого мови - раптом, дізнаєтеся щось корисне! Нарешті, привожу таблицю часу зчитування (в секундах) чисел типу double за допомогою двох розглянутих методів в залежності від їх кількості: