Java inputstream read example

InputStream/OutputStream

— Привет, Амиго! Сегодня мы снова будем заниматься разбором работы InputStream и OutputStream. На самом деле, то первое объяснение было немного упрощенным. Это не интерфейсы, а абстрактные классы, и они даже имеют по паре реализованных методов. Давай посмотрим, какие методы у них есть:

— Т.е. мы можем читать не только по одному байту, а и целыми блоками?

— А записывать целыми блоками тоже можно?

void write(byte[] buff, int from, int count);

— А как будет выглядеть код копирования файла, если мы будем читать не по одному байту, а целыми блоками?

public static void main(String[] args) throws Exception < //Создаем поток-чтения-байт-из-файла FileInputStream inputStream = new FileInputStream("c:/data.txt"); // Создаем поток-записи-байт-в-файл FileOutputStream outputStream = new FileOutputStream("c:/result.txt"); byte[] buffer = new byte[1000]; while (inputStream.available() > 0) //пока есть еще непрочитанные байты < // прочитать очередной блок байт в переменную buffer и реальное количество в count int count = inputStream.read(buffer); outputStream.write(buffer, 0, count); //записать блок(часть блока) во второй поток > inputStream.close(); //закрываем оба потока. Они больше не нужны. outputStream.close(); >

— С буфером все понятно, а что это за переменная count?

— Когда мы читаем самый последний блок данных в файле, может оказаться, что байт осталось не 1000, а, скажем, 328. Тогда и при записи нужно указать, что записать не весь блок, а только его первые 328 байт.

Читайте также:  Convert utc time to local time python

Метод read при чтении последнего блока вернет значение равное количеству реально прочитанных байт. Для всех чтений – 1000, а для последнего блока – 328.

Поэтому при записи блока мы указываем, что нужно записать не все байты из буфера, а только 328 (т.е. значение, хранимое в переменной count).

— Теперь понятно, как все это работает. Спасибо, Элли.

Java-университет

При вызове inputStream.read(buffer), метод read читает байты из потока inputStream и записывает их в массив buffer. Он пытается заполнить массив buffer байтами из потока до тех пор, пока не будет прочитано buffer.length байт или пока не будет достигнут конец потока. Метод read возвращает количество фактически прочитанных байтов. В данном коде buffer используется для временного хранения прочитанных байтов перед записью их в другой поток outputStream. Чтение из потока inputStream в buffer происходит блоками размером 1000 байт. Затем эти блоки записываются в поток outputStream с помощью outputStream.write(buffer, 0, count), где count — количество прочитанных байтов. Таким образом, чтение из файла «c:/data.txt» осуществляется через поток inputStream, а массив buffer служит для временного хранения прочитанных байтов перед записью в выходной файл.

«На самом деле, то первое объяснение было немного упрощенным. Это не интерфейсы, а абстрактные классы. » не понял я смысл этого приема, только запутали) Но хорошо, что автору не пришло в голову сделать, например, «тройной обман». Спасибо за статью😃👍

 byte[] buffer = new byte[1000]; /* тут вроде как обьявляем и инициализируем массив buffer, типа byte размером 1000, но пока заполненный null'ами */ while (inputStream.available() > 0) //пока есть еще непрочитанные байты (ну это понятно) < // а вот тут становится интереснее .. int count = inputStream.read(buffer); /* 1) inputStream.read(buffer) --- метод read читает переданный аргумент buffer, но buffer же вроде как еще нуллами заполнен ?! 2) или же метод read (записывает) заполняет переданный аргумет buffer ? (где-то там, внутри, под капотом) */ outputStream.write(buffer, 0, count); >

Так ребята, кто не понял тему выше, я с помощью добрых людей разобрался + поклацал в компиляторе многократно и вот что имеем: FileInputStream inputStream = new FileInputStream(«c:/data.txt»); FileOutputStream outputStream = new FileOutputStream(«c:/result.txt»); byte[] buffer = new byte[1000]; while (inputStream.available() > 0) < int count = inputStream.read(buffer); outputStream.write(buffer, 0, count);>К примеру файл у нас 1800 байт (символов) byte[] buffer = new byte[1000]; создается массив на 1000 элементов. в первом проходе цикла он полностью заполняется. в нем 1000 ячеек заполнены символами в виде байтов. int count = inputStream.read(buffer); его читает и получает число 1000 — массив полностью заполнен. outputStream.write(buffer, 0, count) записывается из buffer ячейки с нулевой по 1000 (не включается последний элемент) по 999 фактически. во втором проходе цикла (у нас цикл как-бы while (inputStream.available() > 0)) те что остались 800 недочитанные снова попадают в массив перетирая то что там есть. Перетирает только то что заполняется т.е. первые 800. int count становится 800 outputStream.write(buffer, 0, count); записывает ячейки с 0 до 800. Если этот count не считать и не указывать при записи т.е. сделать вот так outputStream.write(buffer); то при первом проходе будет все ок 1000 запишется, а при втором запишутся 800 вновь прочитанные + 200 которые не перетерлись с прошлого раза в массиве. Можно создать массив сразу под полное количество байт, чтоб не разбивать byte[] buffer = new byte[inputStream.available] но мне человек сказал что у буфера есть ограничение и лучше так не делать. Лучше наверное через ArrayList.его можно бесконечно добавлять. Надеюсь комуто помог. Могут быть неточности предупреждаю сразу )

 метод читает один байт и возвращает его как результат. Результат расширяется до int, для красоты. Если все байты уже прочитаны, метод вернет «-1». 

Сомневаюсь, что это было сделано «для красоты». В Java используются байты «со знаком» от -128 до 127. Метод читает беззнаковые байты в диапазоне 0-255, их значения 128-255 просто не влезут в Java-шный байт. Поэтому используют int, хотя могли бы short. Stackoverflow

Источник

Java InputStream

Java InputStream tutorial shows how to work with InputStream class in Java.

is a flow of data from a source or into a destination. A good metaphor for Java streams is water flowing from a tap into a bathtub and later into a drainage. InputStream and OutputStream are abstractions over low-level access to data, such as C file pointers.

Java InputStream

InputStream is a source for reading data. A stream can represent various kinds of sources, including disk files, devices, other programs, and memory arrays.

Streams support many different types of data, including simple bytes, primitive data types, localized characters, and objects.

Java InputStream subclasses

InputStream is an abstract class; it is a superclass for all classes representing an input stream of bytes, including AudioInputStream , ByteArrayInputStream , FileInputStream , FilterInputStream , ObjectInputStream , PipedInputStream , and SequenceInputStream .

Java InputStream close

The FileInputStream’s close method closes the input stream and releases any system resources associated with this stream. In our examples we use try-with-resources statement, which ensures that each resource is closed at the end of the statement.

Java InputStream read

  • read(byte[] b) — reads up to b.length bytes of data from this input stream into an array of bytes.
  • read(byte[] b, int off, int len) — reads up to len bytes of data from this input stream into an array of bytes.
  • read — reads one byte from the file input stream.

Java InputStream read text

The following example shows how to read a text file with InputStream .

The Battle of Thermopylae was fought between an alliance of Greek city-states, led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the course of three days, during the second Persian invasion of Greece.

In the example, we use this text file.

package com.zetcode; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; public class JavaInputStreamText < public static void main(String[] args) throws IOException < String fileName = "src/resources/thermopylae.txt"; try (InputStream fis = new FileInputStream(fileName); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) < br.lines().forEach(line ->System.out.println(line)); > > >

The text file is read with FileInputStream , InputStreamReader , and BufferedReader .

try (InputStream fis = new FileInputStream(fileName);

FileInputStream is a specialization of the InputStream for reading bytes from a file.

InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);

InputStreamReader is a bridge from byte streams to character streams: it reads bytes and decodes them into characters using a specified charset.

BufferedReader br = new BufferedReader(isr)) 

BufferedReader reads text from a character-input stream, buffering characters for efficient reading of characters, arrays, and lines.

br.lines().forEach(line -> System.out.println(line));

The data is read by lines from a buffered reader.

Java InputStream read bytes

The read methods of InputStream read bytes.

package com.zetcode; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class JavaInputStreamBytes < public static void main(String[] args) throws IOException < String fileName = "src/resources/ball.png"; try (InputStream is = new FileInputStream(fileName)) < byte[] buffer = new byte[is.available()]; is.read(buffer); int i = 0; for (byte b: buffer) < if (i % 10 == 0) < System.out.println(); >System.out.printf("%02x ", b); i++; > > System.out.println(); > >

The example reads bytes from a PNG image and prints the bytes in hexadecimal format to the console.

try (InputStream is = new FileInputStream(fileName)) 

We use FileInputStream to read bytes from an image file.

byte[] buffer = new byte[is.available()]; is.read(buffer);

With the read method, we read the bytes into the array of bytes.

int i = 0; for (byte b: buffer) < if (i % 10 == 0) < System.out.println(); >System.out.printf("%02x ", b); i++; >

We go through the array and print the bytes to the console in hexadecimal format.

89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 0a 00 00 00 0a 08 06 00 00 00 8d 32 cf bd 00 00 00 04 73 42 49 54 08 08 08 08 7c 08 64 88 00 00 00 09 70 48 59 73 00 00 0d d7 00 00 0d d7 01 42 28 9b 78 00 00 00 19 74 45 58 74 53 6f .

This is a partial sample output of the example.

Java InputStream read from URL

InputStream allows to read data from a URL source.

package com.zetcode; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; public class JavaInputStreamURL < public static void main(String[] args) throws IOException < String webSite = "http://www.something.com"; URL url = new URL(webSite); try (InputStream is = url.openStream(); BufferedReader br = new BufferedReader( new InputStreamReader(is))) < br.lines().forEach(System.out::println); >> >

The example opens an InputStream to a web page and reads its data.

try (InputStream is = url.openStream();

An InputStream to a URL is created with openStream method.

Java InputStream read deserialized data

ObjectInputStream reads serialized data previously written using ObjectOutputStream .

package com.zetcode; import java.io.Serializable; public class Country implements Serializable < static final long serialVersionUID = 42L; private String name; private int population; public Country(String name, int population) < this.name = name; this.population = population; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getPopulation() < return population; >public void setPopulation(int population) < this.population = population; >>

This is the Country bean. We are going to serialize and deserialize a list of countries.

package com.zetcode; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; public class JavaObjectOutputStreamEx < public static void main(String[] args) throws IOException < String fileName = "src/resources/myfile.dat"; try (OutputStream fis = new FileOutputStream(fileName); ObjectOutputStream out = new ObjectOutputStream(fis)) < Listcountries = new ArrayList<>(); countries.add(new Country("Slovakia", 5429000)); countries.add(new Country("Norway", 5271000)); countries.add(new Country("Croatia", 4225000)); countries.add(new Country("Russia", 143439000)); out.writeObject(countries); > > >

The example serializes a list of objects.

A list of countries is written to the ObjectOutputStream .

package com.zetcode; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.util.List; public class JavaInputStreamObjects < public static void main(String[] args) throws IOException, ClassNotFoundException < String fileName = "src/resources/myfile.dat"; try (InputStream fis = new FileInputStream(fileName); ObjectInputStream oin = new ObjectInputStream(fis)) < Listcountries = (List) oin.readObject(); countries.forEach(System.out::println); > > >

We use the ObjectInputStream to read serialized data.

Java InputStream read sequence of streams

SequenceInputStream represents a sequence of input streams. It allows to read from multiple of ordered streams.

package com.zetcode; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; public class JavaInputStreamSequence < public static void main(String[] args) throws IOException < String fileName1 = "src/resources/myfile.txt"; String fileName2 = "src/resources/myfile1.txt"; String fileName3 = "src/resources/myfile2.txt"; try (InputStream is1 = new FileInputStream(fileName1); InputStream is2 = new FileInputStream(fileName2); InputStream is3 = new FileInputStream(fileName3); SequenceInputStream sis1 = new SequenceInputStream(is1, is2); SequenceInputStream sis = new SequenceInputStream(sis1, is3)) < int b = sis.read(); while (b != -1) < System.out.printf("%c", b); b = sis.read(); >System.out.println(); > > >

The example reads from three FileInputStreams .

try (InputStream is1 = new FileInputStream(fileName1); InputStream is2 = new FileInputStream(fileName2); InputStream is3 = new FileInputStream(fileName3); SequenceInputStream sis1 = new SequenceInputStream(is1, is2); SequenceInputStream sis = new SequenceInputStream(sis1, is3)) 

We define three input streams and these streams are placed into SequenceInputStreams .

int b = sis.read(); while (b != -1)

We read the data from the streams with read .

In this article we have presented the Java InputStream class.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

Источник

Оцените статью