Разное

Вывод на консоль java: Java | Консольный ввод-вывод

Java. Система ввода/вывода

Статья проплачена кошками — всемирно известными производителями котят.

Если статья вам понравилась, то можете поддержать проект.

Класс File
Поток
Класс OutputStream
Исключения ввода/вывода

Java имеет в своём составе множество классов, связанных с вводом/выводом данных. Рассмотрим некоторые из них.

Класс File

В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов.

Подробнее о классе java.io.File

Поток

При работе с данными ввода/вывода вам будет часто попадаться термин Поток (Stream). Поток — это абстрактное значение источника или приёмника данных, которые способны обрабатывать информацию. Вы в реальности не видите, как действительно идёт обработка данных в устройствах ввода/вывода, так как это сложно и вам это не нужно. Это как с телевизором — вы не знаете, как сигнал из кабеля превращается в картинку на экране, но вполне можете переключаться между каналами через пульт.

Есть два типа потоков: байтовые и символьные. В некоторых ситуациях символьные потоки более эффективны, чем байтовые.

За ввод и вывод отвечают разные классы Java. Классы, производные от базовых классов InputStream или Reader, имеют методы с именами read() для чтения отдельных байтов или массива байтов (отвечают за ввод данных). Классы, производные от классов OutputStream или Write, имеют методы с именами write() для записи одиночных байтов или массива байтов (отвечают за вывод данных).

Подробнее о классе InputStream

Класс OutputStream

Класс OutputStream — это абстрактный класс, определяющий потоковый байтовый вывод.

В этой категории находятся классы, определяющие, куда направляются ваши данные: в массив байтов (но не напрямую в String; предполагается что вы сможете создать их из массива байтов), в файл или канал.

BufferedOutputStream
Буферизированный выходной поток
ByteArrayOutputStream
Создает буфер в памяти. Все данные, посылаемые в этот поток, размещаются в созданном буфере
DataOutputStream
Выходной поток, включающий методы для записи стандартных типов данных Java
FileOutputStream
Отправка данных в файл на диске. Реализация класса OutputStream
ObjectOutputStream
Выходной поток для объектов
PipedOutputStream
Реализует понятие выходного канала.
FilterOutputStream
Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства.

Методы класса:

  • int close() — закрывает выходной поток. Следующие попытки записи передадут исключение IOException
  • void flush() — финализирует выходное состояние, очищая все буферы вывода
  • abstract void write (int oneByte) — записывает единственный байт в выходной поток
  • void write (byte[] buffer) — записывает полный массив байтов в выходной поток
  • void write (byte[] buffer, int offset, int count) — записывает диапазон из count байт из массива, начиная с смещения
    offset

BufferedOutputStream

Класс BufferedOutputStream не сильно отличается от класса OutputStream, за исключением дополнительного метода flush(), используемого для обеспечения записи данных в буферизируемый поток. Буферы вывода нужно для повышения производительности.

ByteArrayOutputStream

Класс ByteArrayOutputStream использует байтовый массив в выходном потоке. Метод close() можно не вызывать.

DataOutputStream

Класс DataOutputStream позволяет писать элементарные данные в поток через интерфейс DataOutput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.

Класс DataOutputStream расширяет класс FilterOutputStream, который в свою очередь, расширяет класс OutputStream.

Методы интерфейса DataOutput:

  • writeDouble(double value)
  • writeBoolean(boolean value)
  • writeInt(int value)

FileOutputStream

Класс FileOutputStream создаёт объект класса OutputStream, который можно использовать для записи байтов в файл. Создание нового объекта не зависит от того, существует ли заданный файл, так как он создаёт его перед открытием. В случае попытки открытия файла, доступного только для чтения, будет передано исключение.

Классы символьных потоков

Символьные потоки имеют два основных абстрактных класса Reader и Writer, управляющие потоками символов Unicode.

Reader

Методы класса Reader:

  • abstract void close() — закрывает входной поток. Последующие попытки чтения передадут исключение IOException
  • void mark(int readLimit) — помещает метку в текущую позицию во входном потоке
  • boolean markSupported() — возвращает true, если поток поддерживает методы mark() и reset()
  • int read() — возвращает целочисленное представление следующего доступного символа вызывающего входного потока. При достижении конца файла возвращает значение -1. Есть и другие перегруженные версии метода
  • boolean ready() — возвращает значение true, если следующий запрос не будет ожидать.
  • void reset() — сбрасывает указатель ввода в ранее установленную позицию метки
  • logn skip(long charCount) — пропускает указанное число символов ввода, возвращая количество действительно пропущенных символов
BufferedReader
Буферизированный входной символьный поток
CharArrayReader
Входной поток, который читает из символьного массива
FileReader
Входной поток, читающий файл
FilterReader
Фильтрующий читатель
InputStreamReader
Входной поток, транслирующий байты в символы
LineNumberReader
Входной поток, подсчитывающий строки
PipedReader
Входной канал
PushbackReader
Входной поток, позволяющий возвращать символы обратно в поток
Reader
Абстрактный класс, описывающий символьный ввод
StringReader
Входной поток, читающий из строки

Класс BufferedReader

Класс BufferedReader увеличивает производительность за счёт буферизации ввода.

Класс CharArrayReader

Класс CharArrayReader использует символьный массив в качестве источника.

Класс FileReader

Класс FileReader, производный от класса Reader, можно использовать для чтения содержимого файла. В конструкторе класса нужно указать либо путь к файлу, либо объект типа File.

Writer

Класс Writer — абстрактный класс, определяющий символьный потоковый вывод. В случае ошибок все методы класса передают исключение IOException.

Методы класса:

  • Writer append(char c) — добавляет символ в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
  • Writer append(CharSequence csq) — добавляет символы в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
  • Writer append(CharSequence csq, int start, int end) — добавляет диапазон символов в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
  • abstract void close() — закрывает вызывающий поток
  • abstract void flush() — финализирует выходное состояние так, что все буферы очищаются
  • void write(int oneChar) — записывает единственный символ в вызывающий выходной поток. Есть и другие перегруженные версии метода
BufferedWriter
Буферизированный выходной символьный поток
CharArrayWriter
Выходной поток, который пишет в символьный массив
FileWriter
Выходной поток, пишущий в файл
FilterWriter
Фильтрующий писатель
OutputStreamWriter
Выходной поток, транслирующий байты в символы
PipedWriter
Выходной канал
PrintWriter
Выходной поток, включающий методы print() и println()
StringWriter
Выходной поток, пишущий в строку
Writer
Абстрактный класс, описывающий символьный вывод

Класс BufferedWriter

Класс BufferedWriter — это класс, производный от класса Writer,который буферизует вывод. С его помощью можно повысить производительность за счёт снижения количества операций физической записи в выходное устройство.

Класс CharArrayWriter

Класс CharArrayWriter использует массив для выходного потока.

Класс FileWriter

Класс FileWriter создаёт объект класса, производного от класса Writer, который вы можете применять для записи файла. Есть конструкторы, которые позволяют добавить вывод в конец файла. Создание объекта не зависит от наличия файла, он будет создан в случае необходимости. Если файл существует и он доступен только для чтения, то передаётся исключение IOException.

Чтение и запись файлов

Существует множество классов и методов для чтения и записи файлов. Наиболее распространённые из них — классы

FileInputStream и FileOutputStream, которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, нужно создать объект одного из этих файлов, указав имя файла в качестве аргумента конструктора.

FileInputStream(String filename) throws FileNotFoundException
FileOutputStream(String filename) throws FileNotFoundException

В filename нужно указать имя файла, который вы хотите открыть. Если при создании входного потока файл не существует, передаётся исключение FileNotFoundException. Аналогично для выходных потоков, если файл не может быть открыт или создан, также передаётся исключение. Сам класс исключения происходит от класса IOException. Когда выходной файл открыт, любой ранее существовавший файл с тем же именем уничтожается.

После завершения работы с файлом, его необходимо закрыть с помощью метода

close() для освобождения системных ресурсов. Незакрытый файл приводит к утечке памяти.

В JDK 7 метод close() определяется интерфейсом AutoCloseable и можно явно не закрывать файл, а использовать новый оператор try-с-ресурсами, что для Android пока не слишком актуально.

Чтобы читать файл, нужно вызвать метод read(). Когда вызывается этот метод, он читает единственный байт из файла и возвращает его как целое число. Когда будет достигнут конец файла, то метод вернёт значение -1. Примеры использования методов есть в различных статьях на сайте.

Иногда используют вариант, когда метод close() помещается в блок finally. При таком подходе все методы, которые получают доступ к файлу, содержатся в пределах блока try, а блок finally используется для закрытия файла. Таким образом, независимо от того, как закончится блок

try, файл будет закрыт.

Так как исключение FileNotFoundException является подклассом IOException, то не обязательно обрабатывать два исключения отдельно, а оставить только IOException, если вам не нужно отдельно обрабатывать разные причины неудачного открытия файла. Например, если пользователь вводит вручную имя файла, то более конкретное исключение будет к месту.

Для записи в файл используется метод write().

void write(int value) throws IOException

Метод пишет в файл байт, переданный параметром value. Хотя параметр объявлена как целочисленный, в файл записываются только младшие восемь бит. При ошибке записи передаётся исключение.

В JDK 7 есть способ автоматического управления ресурсами:

try (спецификация_ресурса) {
    // использование ресурса
}

Когда в Android будет полноценная поддержка JDK 7, то дополним материал.

Буферизированное чтение из файла — BufferedReader

Чтобы открыть файл для посимвольного чтения, используется класс FileInputReader; имя файла задаётся в виде строки (String) или объекта File. Ускорить процесс чтения помогает буферизация ввода, для этого полученная ссылка передаётся в конструктор класса BufferedReader. Так как в интерфейсе класса имеется метод readLine(), все необходимое для чтения имеется в вашем распоряжении. При достижении конца файла метод readLine() возвращает ссылку null.

Вывод в файл — FileWriter

Объект FileWriter записывает данные в файл. При вводе/выводе практически всегда применяется буферизация, поэтому используется BufferedWriter.

Когда данные входного потока исчерпываются, метод readLine() возвращает null. Для потока явно вызывается метод close(); если не вызвать его для всех выходных файловых потоков, в буферах могут остаться данные, и файл получится неполным.

Сохранение и восстановление данных — PrintWriter

PrintWriter форматирует данные так, чтобы их мог прочитать человек. Однако для вывода информации, предназначенной для другого потока, следует использовать классы DataOutputStream для записи данных и DataInputStream для чтения данных.

Единственным надежным способом записать в поток DataOutputStream строку так, чтобы ее можно было потом правильно считать потоком DataInputStream, является кодирование UTF-8, реализуемое методами readUTF() и writeUTF(). Эти методы позволяют смешивать строки и другие типы данных, записываемые потоком DataOutputStream, так как вы знаете, что строки будут правильно сохранены в Юникоде и их будет просто воспроизвести потоком DataInputStream.

Метод writeDouble() записывает число double в поток, а соответствующий ему метод readDouble() затем восстанавливает его (для других типов также существуют подобные методы).

RandomAccessFile — Чтение/запись файлов с произвольным доступом

Работа с классом RandomAccessFile напоминает использование совмещенных в одном классе потоков DataInputStream и DataOutputStream (они реализуют те же интерфейсы DataInput и DataOutput). Кроме того, метод seek() позволяет переместиться к определенной позиции и изменить хранящееся там значение.

При использовании RandomAccessFile необходимо знать структуру файла. Класс RandomAccessFile содержит методы для чтения и записи примитивов и строк UTF-8.

RandomAccessFile может открываться в режиме чтения («r») или чтения/записи («rw»). Также есть режим «rws», когда файл открывается для операций чтения-записи и каждое изменение данных файла немедленно записывается на физическое устройство.

Исключения ввода/вывода

В большинстве случаев у классов ввода/вывода используется исключение IOException. Второе исключение FileNotFoundException передаётся в тех случаях, когад файл не может быть открыт. Данное исключение происходит от IOException, поэтому оба исключения можно обрабатывать в одном блоке catch, если у вас нет нужды обрабатывать их по отдельности.

Дополнительное чтение

Используем AsyncTask для загрузки текстового файла из сети — используются BufferedReader, InputStreamReader, InputStream.

Реклама

Java дайджест #33: Pattern Matching for Java

DOU шукає журналіста(-ку) в команду. Дізнатись умови та подати своє резюме

  • Головна
  • Форум
  • Стрічка
  • Зарплати
  • Робота
  • Календар
  • Military-tech

Вхід і реєстрація

Посилання · 28 квітня 2017, 10:00 8040

Ссылки, на которые лучше таки нажать (по мнению автора), отмечены знаком (!)

Что-то вроде новостей

(!) Собственно новость месяца: Pattern Matching for Java. На мой взгляд, выглядит странно. У кого какое мнение по этому поводу?

Java EE is moving to GitHub!

Вышел Apache Maven 3.5.0. Появилась самая важная фича — цветной вывод в консоль.

Вышел Gradle 3.5

Вышел Spring Cloud Pipelines 1.0.0.M4. Похоже, что под брендом Spring хотят собрать все тулы для разработки на Java.

Почитать и посмотреть

(!) Bytestacks — флеймграфики для Java.

Java Finalization to be Deprecated?

JVM Anatomy Park #3: GC Design and Pauses

All about java.util.Date. Статья никаких откровений не содержит, но для «закрепления материала» сойдет.

Custom collectors in Java 8. Довольно просто про то, как работают Collectors.

Обзор Spring Boot Actuator.

Java 9

(!) Using JDK 9 Memory Order Modes от Doug Lea.

(!) 3 статьи о модулях Java 9 от Stephen Colebourne:

  • Java 9 modules — JPMS basics
  • Java SE 9 — JPMS module naming
  • Java SE 9 — JPMS modules are not artifacts

Support for Java 9 Modules in IntelliJ IDEA 2017.

1

На сколько Eclipse готов к Java 9

Беспокойства сообщества по поводу Jigsaw.

Is Jigsaw good or is it wack?

Микросервисы

Real World Microservices with Spring Cloud, Netflix OSS and Kubernetes. Сколько баззвордов в одном заголовке.

Ссылка на pdf-книгу из предыдущего доклада.

Java micro-frameworks: Why Jooby?

В jooby появилась поддержка Kotlin. Похоже, что Kotlin будет основной темой хипстерского движения в Java.

Meecrowave — еще один фреймворк для микросервисов.

Аналитика, так сказать

Меряем производительность Java-логгеров.

Java in 2017 Survey Results

Top Java Web Frameworks Popularity Index: March 2017

DZone/Java EE Guardians Survey Results


Предложения и пожелания все еще принимаются или через завсклад и товаровэд администрацию ДОУ, или через твиттер @_silverwolf. Также можно оставлять комментарии в специально выделенной теме на форуме.


← Предыдущий выпуск: Java дайджест #32
Следующий выпуск: Java дайджест #34 →

Все про українське ІТ в телеграмі — підписуйтеся на канал редакції DOU

Теми: Java, Java дайджест

👍ПодобаєтьсяСподобалось0

До обраногоВ обраному0

Facebook

Twitter

LinkedIn

Почему System.

out.println() в Java печатает на консоль?

Я сомневаюсь, что когда мы делаем System.out.println() в нашем коде, почему это заканчивается записью на консоль?

В любой оболочке, совместимой с POSIX, каждый процесс получает три «стандартных» потока при запуске оболочки:

  • Поток «стандартного ввода» предназначен для чтения ввода.
  • Поток «стандартный вывод» предназначен для записи обычного вывода.
  • Поток «стандартной ошибки» предназначен для записи вывода ошибок.

(Та же идея также используется во многих оболочках, несовместимых с POSIX.)

Для интерактивной оболочки POSIX по умолчанию эти потоки считываются и записываются в «консоль» оболочки… которая может быть физической консолью, но, скорее всего, будет «эмулятором терминала» на пользовательском (конечном) настольном компьютере. (Подробности различаются.)

Оболочка POSIX позволяет перенаправлять стандартные потоки различными способами; например

 $ some-command < файл # прочитать стандартный ввод из 'файла'
$ some-command > file # записать stdout в 'file'
$ some-command 2> file # записать stderr в 'file'
$ some-command << EOF # чтение стандартного ввода из документа "здесь"
  строки ввода
  . ..
  EOF
$ какая-то команда | еще # подключить stdout для одной команды к
                          # стандартный ввод для следующего в конвейере
 

и так далее. Если вы сделаете это, один или несколько стандартных потоков НЕ будут подключены к консоли.

Дальнейшее чтение:

  • «Что такое стандартный ввод, стандартный вывод и стандартный вывод в Linux?»
  • «Стандартные потоки»

Итак, как это относится к вопросу?

При запуске Java-программы потоки System.in/out/err подключаются к стандартным потокам ввода/вывода/ошибки, указанным родительским процессом; обычно оболочка.

В случае System.out этот может быть консолью (как бы вы это ни определяли) или может быть файлом, или другой программой, или … /dev/null . Но то, куда идет вывод, определяется тем, как была запущена JVM.

Таким образом, буквальный ответ таков: «потому что это то, что родительский процесс сказал Java-программе».


Как внутренне оболочка взаимодействует с jvm для установки стандартного ввода/вывода как в Windows, так и в Linux?

Это то, что происходит с Linux, UNIX, Mac OSX и подобными. (Я не знаю, для Windows… но я думаю, что это похоже.)

Предположим, что оболочка будет работать aaa > bbb.txt .

  1. Родительская оболочка разветвляет дочерний процесс… разделяя адресное пространство родительской оболочки.
  2. Дочерний процесс закрывает файловый дескриптор 1 (стандартный выходной файловый дескриптор)
  3. Дочерний процесс открывает «bbb.txt» для записи в дескриптор файла 1.
  4. Дочерний процесс выполняет команду «aaa» и становится командным процессом «aaa». Дескрипторы файлов 0, 1 и 2 сохраняются вызовом exec.
  5. Команда «ааа» начинается…

Когда запускается команда «aaa», она обнаруживает, что файловые дескрипторы 0 и 2 (stdin и stderr) относятся к тому же «файлу», что и родительская оболочка. Дескриптор файла 1 (stdout) относится к «bbb.txt».

То же самое происходит, когда «aaa» является командой java .

PPT – Консольный вывод в презентации Java PowerPoint | скачать бесплатно

Об этой презентации

Стенограмма и примечания докладчика

Название: Консольный вывод в Java

1
Консольный вывод в Java

  • Приложение к примечаниям
  • CS 1054 Введение в программу ming in Java
  • Spring 2008
2
печать () и println()

  • До сих пор мы использовали System.out.print и
    System.out.println для вывода
  • С одним аргументом (строка или числовое значение)
  • println() если нам требуется новая строка в конце
    вывод
  • print() чтобы оставаться на текущей строке вывода
3
Вывод значений вокруг строк

  • Предположим, мы хотим напечатать значения двух
    переменных, numCones (int) и unitPrice (double),
    в аккуратном сообщении
  • , например, продал 5 конусов по 2. 50 каждый.
  • Использование print и println,
  • System.out.print(«продано»)
  • System.out.print(numCones)
  • System.out.print(«cones at»)
  • System.out.print( unitPrice )
  • System.out.println(» каждый.» )
4
Конкатенация строк

  • Можно использовать оператор над строками
  • Если оба аргумента являются строками, это просто
    объединены или объединены, например,
  • «Корзина» «мяч» равно «Баскетбол»
  • «Привет,» имя равно «Привет, Боб» при условии, что имя имеет
    значение «Боб»
  • Если один аргумент является числом, этот аргумент
    преобразуется в строку
  • «Привет,» 5 равно «Привет, » «5» «Привет, 5»
  • «Price» unitPrice равно «Price 2.50»
    если цена имеет значение 2.50
5
Использование конкатенации с print и println

  • Улучшенная версия
  • System.out .print(«продано» numCones )
  • System. out.println( » конусы в » unitPrice »
    каждый.» )
  • Фактически может быть сжат в один оператор println
  • Обратите внимание, что метод print или println по-прежнему имеет
    один аргумент даже в этих случаях (строка )
6
Форматирование строк

  • Обратите внимание, что, особенно с числами с плавающей запятой
    , мы не можем контролировать, сколько пробелов
    занимает число при печати
  • например, 5 конусов продаются по 2 .4999998 каждый
  • Что было бы предпочтительнее, так это иметь возможность
    указывать, до скольких знаков после запятой
    разрешено
  • Можно сделать на Java с помощью метода printf()
7
Метод printf() 900 06
  • Еще лучшая версия
  • System.out.printf(«продано d конусов по 0,2f по
    каждый.\n»,numCones, unitPrice )
  • печатает 5 конусов по 2,50 каждый
  • Больше контроля
  • System.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *