DataInputStream.readInt: примеры (JAVA)
DataInputStream.readInt: intОбщее описание DataInputStream.readInt
Метод readInt класса java.io.DataInputStream читает 4 байта из входного потока и возвращает 32-битное целое число со знаком (тип int). Подпись метода:
public final int readInt() throws IOException
Особенности поведения:
- Чтение производится в порядке big-endian (старший байт первым), то есть соответствие байтов и значений совпадает с сетевым порядком байт.
- Аргументов не принимает: метод использует уже открытый поток, обёрнутый в DataInputStream.
- Возвращает значение типа
int(32-битное со знаком). - При достижении конца потока до получения 4 байт бросается
java.io.EOFException. При других проблемах ввода-вывода бросаетсяjava.io.IOException. - Метод реализует контракт интерфейса
DataInput; порядок байт фиксирован и не зависит от платформы JVM.
Частые сценарии применения: чтение бинарных форматов с фиксированной шириной целых, чтение данных, записанных с помощью DataOutputStream.writeInt, обработка сетевых протоколов, где интегер передаётся в 4 байта big-endian.
Примеры простого использования
Чтение значения, записанного с помощью DataOutputStream:
// Java
import java.io.*;
public class Example1 {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(0x01020304); // записывает 4 байта
dos.close();
byte[] data = baos.toByteArray();
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
int v = dis.readInt();
System.out.println(v);
}
}
16909060
Чтение из файла (файл содержит последовательность 4-байтовых целых):
// Java
import java.io.*;
public class Example2 {
public static void main(String[] args) throws Exception {
try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("ints.bin")))) {
while (true) {
int x = dis.readInt();
System.out.println(x);
}
} catch (EOFException eof) {
// конец файла
System.out.println("Конец файла");
}
}
}
(пример вывода - последовательность чисел, затем "Конец файла")
Ситуация, когда байтов не хватает - демонстрация EOFException:
// Java
import java.io.*;
public class Example3 {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[] {0x01, 0x02}; // только 2 байта
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
dis.readInt();
}
}
java.io.EOFException at java.base/java.io.DataInputStream.readInt(DataInputStream.java:...) ...
Похожие методы в Java и их различия
- ByteBuffer.getInt() - чтение int из буфера байтов с управляемым порядком байт (можно задать ByteOrder.BIG_ENDIAN или LITTLE_ENDIAN). Предпочтение при необходимости управления порядком байт и при работе с NIO.
- RandomAccessFile.readInt() - похож на DataInputStream.readInt, но позволяет читать по произвольным смещениям в файле (поддерживает seek).
- DataInput.readInt() - интерфейсный метод; разные реализации могут использовать тот же алгоритм, но поведение зависит от конкретной реализации.
- ObjectInputStream.readInt() - читает int в контексте сериализованного потока объектов; лишний служебный контекст может присутствовать при чтении сложных объектов.
Выбор между ними зависит от потребностей: для простого последовательного чтения из InputStream - DataInputStream, для управления порядком байт и высокопроизводительных операций с буферами - ByteBuffer, для доступа по смещению в файле - RandomAccessFile.
Аналоги в других языках и отличия
PHP (работа с бинарными данными):
// PHP
$data = chr(0x01).chr(0x02).chr(0x03).chr(0x04);
$val = unpack('N', $data)[1]; // N - unsigned long (big-endian)
echo $val . PHP_EOL;
16909060
JavaScript (Node.js Buffer и Web API DataView):
// Node.js
const buf = Buffer.from([0x01,0x02,0x03,0x04]);
console.log(buf.readInt32BE(0));
// Браузер: DataView
const arr = new Uint8Array([1,2,3,4]);
const v = new DataView(arr.buffer).getInt32(0, false); // false = big-endian
console.log(v);
16909060 16909060
Python (struct и int.from_bytes):
# Python
import struct
b = bytes([1,2,3,4])
print(struct.unpack('>i', b)[0])
# или
print(int.from_bytes(b, byteorder='big', signed=True))
16909060 16909060
C# (.NET):
// C#
using System;
using System.IO;
byte[] bytes = new byte[]{1,2,3,4};
using(var ms = new MemoryStream(bytes)){
using(var br = new BinaryReader(ms)){
Console.WriteLine(br.ReadInt32()); // окружение Little-endian у CLR, но BinaryReader читает в порядке платформы; если данные big-endian - требуется перестановка
}
}
16909060 (если платформа и формат совпадают) или неправильное число, если порядок байт отличается
Go (encoding/binary):
// Go
package main
import (
"encoding/binary"
"fmt"
)
func main() {
b := []byte{1,2,3,4}
v := int32(binary.BigEndian.Uint32(b))
fmt.Println(v)
}
16909060
Lua (5.3+):
-- Lua
local s = string.char(1,2,3,4)
local v = string.unpack('>i4', s)
print(v)
16909060
Ключевые различия от Java:
- Порядок байт может требовать явной настройки (в Java DataInputStream фиксирован как big-endian).
- Некоторые языки имеют встроенные функции для чтения из буфера с параметризуемым порядком байт.
- В C# BinaryReader читает в порядке платформы; при работе с big-endian требуется преобразование.
Типичные ошибки и примеры
- EOFException при чтении недостаточного количества байт. Пример:
// Java
import java.io.*;
public class Err1 {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[]{0x01};
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
dis.readInt(); // бросит EOFException
}
}
java.io.EOFException at java.base/java.io.DataInputStream.readInt(DataInputStream.java:...) ...
- Неправильный результат при неверном порядке байт (little-endian вместо big-endian). Пример:
// Java
byte[] b = new byte[]{0x01,0x02,0x03,0x04};
int v = new DataInputStream(new ByteArrayInputStream(b)).readInt();
System.out.println(v);
// Если данные были записаны как little-endian, значение будет некорректным
16909060
- Попытка читать бинарные int через текстовые Reader/BufferedReader ведёт к неверным данным и возможным ошибкам кодирования.
- Игнорирование закрытия потоков может привести к утечкам ресурсов. Рекомендуется try-with-resources.
- Смешивание методов чтения (например, чтение байтов и сразу чтение символов без согласования формата) может сместить позицию и испортить последующие readInt.
Изменения в поведении метода в последних версиях JDK
Метод DataInputStream.readInt() существует с ранних версий JDK и сохраняет стабильное поведение: чтение 4 байт в порядке big-endian и выброс EOFException при нехватке байт. В современных релизах Java не было обратимо несовместимых изменений в семантике этого метода. Следует учитывать общие изменения платформы, например, улучшения производительности JDK и модульность (JDK 9), но интерфейс и контракт метода остался прежним.
Расширенные и нестандартные сценарии
1) Быстрое чтение большого массива int: чтение блоками байтов с последующей упаковкой в IntBuffer.
// Java
import java.io.*;
import java.nio.*;
public class Adv1 {
public static void main(String[] args) throws Exception {
// предположим, что stream содержит 1000 int подряд (big-endian)
InputStream is = /* источник */ new FileInputStream("ints.bin");
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
int count = 1000;
byte[] buf = new byte[count * 4];
dis.readFully(buf); // выбросит EOFException, если байтов меньше
IntBuffer ib = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN).asIntBuffer();
while (ib.hasRemaining()) {
System.out.println(ib.get());
}
dis.close();
}
}
(вывод - 1000 чисел из файла)
2) Обработка little-endian входа при помощи ручной перестановки или ByteBuffer.order:
// Java
import java.io.*;
import java.nio.*;
byte[] b = new byte[]{0x04,0x03,0x02,0x01}; // little-endian представление 0x01020304
int v = ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.println(v);
16909060
3) Чтение int из сетевого сокета с обработкой неполных пакетов:
// Java
import java.io.*;
import java.net.*;
public class NetRead {
public static void main(String[] args) throws Exception {
try (Socket s = new Socket("example.com", 12345);
DataInputStream dis = new DataInputStream(s.getInputStream())) {
// цикл чтения, аккуратно обрабатывается EOF и блокировки
while (true) {
try {
int cmd = dis.readInt();
// обработка команды
} catch (EOFException eof) {
break; // соединение закрыто корректно
}
}
}
}
}
(выполнение зависит от удалённого сервера)
4) Сочетание с MemoryMappedFile для произвольного доступа к большим бинарным файлам:
// Java
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
RandomAccessFile raf = new RandomAccessFile("large.bin","r");
FileChannel ch = raf.getChannel();
MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size());
mb.order(ByteOrder.BIG_ENDIAN);
IntBuffer ib = mb.asIntBuffer();
System.out.println(ib.get(10)); // десятый int в файле
ch.close();
raf.close();
(значение в позиции 10 файла)
5) Обработка смешанных форматов: чтение int, затем строки фиксированной длины и байтовых блоков с контролем смещения.
// Java
DataInputStream dis = new DataInputStream(new FileInputStream("mix.bin"));
int header = dis.readInt(); // 4 байта
byte[] nameBytes = new byte[16];
dis.readFully(nameBytes);
String name = new String(nameBytes, "UTF-8").trim();
int payloadLen = dis.readInt();
byte[] payload = new byte[payloadLen];
dis.readFully(payload);
(обработка зависимости от содержимого mix.bin)
В комментариях к примерам приведена типовая обработка ошибок и варианты применения при больших данных.
джава DataInputStream.readInt function comments
- джава DataInputStream.readInt - аргументы и возвращаемое значение
- Функция java DataInputStream.readInt - описание
- DataInputStream.readInt - примеры
- DataInputStream.readInt - похожие методы на java
- DataInputStream.readInt на javascript, c#, python, php
- DataInputStream.readInt изменения java
- Примеры DataInputStream.readInt на джава