Почему InputStream # read () возвращает int, а не байт?
Почему InputStream#read() возвращает int , а не byte ?
6 ответов
Потому что byte может удерживать только -128 до 127, тогда как он должен возвращать 0 до 255 (и -1, когда нет байта слева (то есть EOF)). Даже если он вернется byte , не будет места для представления EOF.
Более интересный вопрос заключается в том, почему он не возвращает short .
Он возвращает int, потому что, когда поток больше не читается, он возвращает -1.
Если он возвращает байт, то -1 не может быть возвращен, чтобы указать ошибку, потому что -1 является допустимым байтом. Кроме того, вы не можете вернуть значение выше 127 или ниже -128, потому что Java обрабатывает только подписанные байты.
Много раз, когда вы читаете файл, вам нужны неподписанные байты для вашего кода обработки. Чтобы получить значения от 128 до 255, вы можете использовать короткий, но с помощью int вы будете более эффективно выравнивать регистры памяти с вашей шиной данных. В результате вы действительно не теряете какую-либо информацию, используя int, и вы, вероятно, получаете немного производительности. Единственным недостатком является стоимость памяти, но, скорее всего, вы не будете долго висеть на этом int (как вы ее обработаете и превратите в char или byte []).
Метод read()
Что делает метод read? Почему он возвращает int а не byte? Почему он не может возвращать byte?
* Reads the next byte of data from the input stream. The value byte is
* returned as an <@code int>in the range <@code 0>to
* <@code 255>. If no byte is available because the end of the stream
* has been reached, the value <@code -1>is returned. This method
* blocks until input data is available, the end of the stream is detected,* or an exception is thrown.
Тип Int необходим для возможности выделять признак конца потока. Т.к. тип byte является знаковым, то его диапазон составляет [-128; 127], ([1000_0000; 0111_1111]), но если этот байт поместить в младший байт типа int, то диапазон значений становится [0; 255].
Что вернет метод read(), если он считывает файл и ему встречается байт равный -1?
-1 в типе int =
1111_1111__1111_1111__1111_1111__1111_1111
-1 в байте, помещенном в int =
0000_0000__0000_0000__0000_0000__1111_1111
или 255.
Перегрузки метода read() у inputStream
читает последовательно 1 байт из потока
читает из потока массив байт длинной b.length, либо меньше и сохраняет его в буферный массив b.
Возвращает количество реально переданных байт, либо -1 если поток закончился.
всё то же самое, что и предыдущий, только первый байт помещается в элемент массива b[off], следующий в b[off+1] и т.д.
Why does InputStream#read() return an int and not a byte?
When reading data from an InputStream in Java, you may have noticed that the `read()` method returns an `int` instead of a `byte`. This behavior may seem odd at first, but there are actually good reasons for it.
The need for error detection
One of the main reasons that `read()` returns an `int` instead of a `byte` is to allow for error detection. The `read()` method returns the next byte of data from the stream as an `int`. However, if the end of the stream has been reached, `read()` returns -1 instead of a byte value. This allows the calling code to detect the end of the stream and take appropriate action.
Here is an example of how `read()` can be used to read data from a file:
In this example, the `read()` method is called in a loop until it returns -1, indicating that the end of the file has been reached.
The need for data conversion
Another reason that `read()` returns an `int` instead of a `byte` is to allow for data conversion. In Java, bytes are signed values, which means that they have a range of -128 to 127. However, many data formats (such as image formats) use unsigned byte values, which have a range of 0 to 255. By returning the next byte of data as an `int`, the calling code can easily convert the signed byte value to an unsigned value if necessary.
Here is an example of how `read()` can be used to read unsigned byte values from a file:
In this example, the `read()` method is used to read the next byte of data from a JPEG image file. The `& 0xff` operation is used to convert the signed byte value to an unsigned value.
Conclusion
In summary, the decision to have `read()` return an `int` instead of a `byte` was made to allow for error detection and data conversion. By returning an `int`, the calling code can detect the end of the stream and convert signed byte values to unsigned values if necessary.
Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Тип данных int в Java является дополненнным до двух целым числом и использует 32 бита вместо 8.
В 32х битном виде число 253 будет:
т. е. метод read() возвращает не само значение byte, а его представление в 32х битном виде.
Как хранятся значения в int в byte
| число | 32 bit | 8 bit |
| -128 | 11111111111111111111111110000000 | 10000000 |
| -127 | 11111111111111111111111110000001 | 10000001 |
| -126 | 11111111111111111111111110000010 | 10000010 |
| -125 | 11111111111111111111111110000011 | 10000011 |
| -2 | 11111111111111111111111111111110 | 11111110 |
| -1 | 11111111111111111111111111111111 | 11111111 |
| 0 | 00000000000000000000000000000000 | 00000000 |
| 1 | 00000000000000000000000000000001 | 00000001 |
| 2 | 00000000000000000000000000000010 | 00000010 |
| 125 | 00000000000000000000000001111101 | 01111101 |
| 126 | 00000000000000000000000001111110 | 01111110 |
| 127 | 00000000000000000000000001111111 | 01111111 |
Диапазон byte в Java лежит от -128 до 127, а возвращаемое значение метода read() лежит в диапазоне от 0 до 255.
Что происходит с числом byte в методе read
Чтобы получить представление byte в int в методе read() используется побитовое «И» c числом 255, т. е. убираем лидирующие единицы.
Чтобы из представления получить обратно значение byte в int, нужно выполнить обратную операцию побитовое «ИЛИ» c числом -256, т. е. добавляем лидирующие единицы.
Что происходит с числом byte == -1 в методе read()
То же самое: убираем лидирующие единицы.
5) Как создать файл на компьютере с помощью java.
Класс File, определенный в пакете java.io, не работает напрямую с потоками. Его задачей является управление информацией о файлах и каталогах. Хотя на уровне операционной системы файлы и каталоги отличаются, но в Java они описываются одним классом File.
File(String путь_к_каталогу, String имя_файла)
File dir1 = new File(«C://SomeDir«);
// создаем объекты для файлов, которые находятся в каталоге
File file1 = new File(«C://SomeDir«, «Hello.txt»);
- boolean createNewFile(): создает новый файл по пути, который передан в конструктор. В случае удачного создания возвращает true, иначе false
- boolean delete(): удаляет каталог или файл по пути, который передан в конструктор. При удачном удалении возвращает true.
- boolean exists(): проверяет, существует ли по указанному в конструкторе пути файл или каталог. И если файл или каталог существует, то возвращает true, иначе возвращает false
- String getAbsolutePath(): возвращает абсолютный путь для пути, переданного в конструктор объекта
- String getName(): возвращает краткое имя файла или каталога
- String getParent(): возвращает имя родительского каталога
- boolean isDirectory(): возвращает значение true, если по указанному пути располагается каталог
- boolean isFile(): возвращает значение true, если по указанному пути находится файл
- boolean isHidden(): возвращает значение true, если каталог или файл являются скрытыми
- long length(): возвращает размер файла в байтах
- long lastModified(): возвращает время последнего изменения файла или каталога. Значение представляет количество миллисекунд, прошедших с начала эпохи Unix
- String[] list(): возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге
- File[] listFiles(): возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге
- boolean mkdir(): создает новый каталог и при удачном создании возвращает значение true
- boolean renameTo(File dest): переименовывает файл или каталог
Работа с каталогами
public class Program <
public static void main(String[] args) <
// определяем объект для каталога
File dir = new File(«C://SomeDir«);
// если объект представляет каталог
for(File item : dir.listFiles())<
System.out.println(item.getName() + » \t folder»);
System.out.println(item.getName() + «\t file»);
public class Program <
public static void main(String[] args) <
// определяем объект для каталога
File dir = new File(«C://SomeDir//NewDir«);
boolean created = dir.mkdir();
System.out.println(«Folder has been created»);
File newDir = new File(«C://SomeDir//NewDirRenamed«);
boolean deleted = newDir.delete();
System.out.println(«Folder has been deleted»);
Работа с файлами
public class Program <
public static void main(String[] args) <
// определяем объект для каталога
File myFile = new File(«C://SomeDir//notes.txt«);
System.out.println(«File name: » + myFile.getName());
System.out.println(«Parent folder: » + myFile.getParent());
System.out.println(«File not found»);
System.out.println(«File size: » + myFile.length());
System.out.println(«File can be read»);
System.out.println(«File can not be read»);
System.out.println(«File can be written»);
System.out.println(«File can not be written»);
// создадим новый файл
File newFile = new File(«C://SomeDir//MyFile«);
boolean created = newFile.createNewFile();
System.out.println(«File has been created»);
6) Как удалить директорию с файлами.
Java не может удалять папки с данными в нем. Перед удалением папки необходимо удалить все файлы . использовать что-то вроде:
String []entries = index.list ();
for (String s: entries) <
File currentFile = new File (index.getPath (), s);
тогда вы сможете удалить папку , используя index . delete ().
deleteDirectory
Deletes a directory recursively.
Parameters:
directory — directory to delete
Throws:
IOException — in case deletion is unsuccessful
deleteQuietly
Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
- A directory to be deleted does not have to be empty.
- No exceptions are thrown when a file or directory cannot be deleted.
- A directory to be deleted does not have to be empty.
- You get exceptions when a file or directory cannot be deleted. (java.io.File methods returns a boolean)
file — file or directory to delete, can be null
Returns:
true if the file or directory was deleted, otherwise false
Since:
forceDelete
Deletes a file. If file is a directory, delete it and all sub-directories.
file — file or directory to delete, must not be null
Throws:
NullPointerException — if the directory is null
FileNotFoundException — if the file was not found
forceDeleteOnExit
Schedules a file to be deleted when JVM exits. If file is directory delete it and all sub-directories.
Parameters:
file — file or directory to delete, must not be null
Throws:
NullPointerException — if the file is null
IOException — in case deletion is unsuccessful
Это лучшее решение для Java 7+ :
public static void deleteDirectory(String directoryFilePath) throws IOException
Path directory = Paths.get(directoryFilePath);
if (Files.exists(directory))
Files.walkFileTree(directory, new SimpleFileVisitor
()
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
7) Что такое сериализация и десериализация.
Сериализация представляет процесс записи состояния объекта в поток, соответственно процесс извлечения или восстановления состояния объекта из потока называется десериализацией. Сериализация очень удобна, когда идет работа со сложными объектами.
Интерфейс Serializable
Сериализация. Класс ObjectOutputStream
Для сериализации объектов в поток используется класс ObjectOutputStream. Он записывает данные в поток.