问题1:为什么InputStream.read()读取一个byte却返回一个int呢?
InputStream.read()返回一个unsigned byte [0 - 255],而java里面没有这个类型,所以用int接收。
byte的范围是[-128,127],所以如果read()返回的数在[128,255]的范围内时,则表示负数,即
(byte)128=-128
(byte)129=-127
(byte)255=-1
所以如果read()返回的是byte的话,那就会有负数。而"返回-1意味着结束",这个信息量用byte是无法表达的,所以必须用int。
问题2:如何把一个整数(int)正确保存到一个byte数组,并从里面正确的读出来?
先看代码再解释:
public static int readInt(byte[] readBuffer, int offset) { int i = offset; //readBuffer[i]范围是[-128,127],转整形时必须是[0,255] int ch1 = readBuffer[i++] & 255; int ch2 = readBuffer[i++] & 255; int ch3 = readBuffer[i++] & 255; int ch4 = readBuffer[i++] & 255; return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } public static void writeInt(int v, byte[] writeBuffer, int offset) { int i = offset; //这里面会存在负数 writeBuffer[i++] = (byte) (v >>> 24); writeBuffer[i++] = (byte) (v >>> 16); writeBuffer[i++] = (byte) (v >>> 8); writeBuffer[i++] = (byte) (v >>> 0); }
对于writeInt:v无符号右移>>>肯定是正数,即[0,255],用byte强转型后就可能负数[-128,127]。
对于readInt:readBuffer[i++]是有负数的,必须转成无符号整形,即&255变成[0,255]范围之后才可以用于组装int。
延伸3:
OutputStream.write(int b):相当与write(b&255),
如果你write(-2),因为-2&255=254,那么相应的r = InputStream.read()返回的是254,需要(int) (byte) r才能获取你想要的值((byte)254=-2)
结论:可以认为OutputStream和InputStream里面都是unsigned byte。
相关推荐
我们可以创建一个自定义的`HttpServletRequestWrapper`子类,重写`getInputStream()`方法,使其返回一个可以重复读取的`InputStream`。 以下是一个简单的自定义`HttpServletRequestWrapper`示例: ```java import ...
这段代码首先使用`ImageIO.read(file)`方法从给定的文件中读取图片,然后调用`ImageIO.write()`方法将图片写入一个内存中的`ByteArrayOutputStream`,并返回其字节数据。 接下来,我们讨论如何“合并inputStream...
该函数创建了一个`ByteArrayOutputStream`对象,然后逐个读取`InputStream`中的字节并写入`ByteArrayOutputStream`中,最后转换为`byte[]`数组。 2. **byte[]转InputStream** ```java public InputStream ...
- `public int read(byte[] b, int off, int len) throws IOException`: 类似于上一个方法,但可以指定在数组`b`的哪个偏移量`off`开始存储,以及最多读取`len`个字节。 - `public void reset() throws IOException`...
- `java.io.InputStream.read(byte[] b, int off, int len)`: 读取数据到字节数组,返回读取的字节数。 - `java.io.InputStream.close()`: 关闭输入流并释放与流相关的系统资源。 2. 多线程编程 - `java.lang....
首先,`javax.comm`库是Sun Microsystems为Java设计的一个API,主要用于串行通信。它提供了`CommPortIdentifier`、`SerialPort`和`ParallelPort`等类,用于识别和管理串行和并行端口。然而,需要注意的是,自Java 6...
在Java编程中,有时我们可能需要将一个已经写入数据的`OutputStream`转换为`InputStream`,以便重新读取这些数据。这种情况通常出现在临时存储或处理数据时,例如在网络传输或者存储到内存中的场景。本篇文章将深入...
1. 首先,在`res/raw`目录下创建一个名为`my_raw_file.raw`的文件,该文件将包含我们要读取的数据。 2. 在代码中,我们需要通过`Resources`对象来获取`InputStream`。`Resources`对象可以从`Context`获取,如下所示...
`read(byte[] b)`尝试读取`b.length`个字节到字节数组`b`中,但不保证一定能读取这么多,可能只读取到一个或部分。而`read(byte[] b, int off, int len)`允许指定起始偏移量`off`和最大读取长度`len`。需要注意的是...
然后,你可以使用`ImageIO.read(file)`方法,其中`file`是一个指向图像文件的`File`对象。例如: ```java File imageFile = new File("path/to/image.jpg"); BufferedImage image = ImageIO.read(imageFile); ``...
在本例中,我们将探讨如何从`assets`文件夹中读取音频文件,并提供一个简单的示例。 首先,了解`assets`文件夹的定位:它位于你的Android项目结构中的`src/main/assets`目录下。在这里放置的文件不会被Android...
1. **`read()`**:从输入流中读取下一个字节。 2. **`read(byte[] b)`**:从输入流中读取一定数量的字节,并将其存储在指定的字节数组`b`中。 3. **`read(byte[] b, int off, int len)`**:从输入流中读取最多`len`...
返回值类型为int,而不是byte,是因为read方法返回的值一定是一个八位的二进制,可以取值的值区间为 [-128,127]。 4. InputStream中的其他方法 InputStream中还有其他几个方法,如read(byte b[])、read(byte b[], ...
- **使用`BufferedInputStream`**:这是一个包装器类,可以在基本的`InputStream`基础上提供缓冲功能,从而提高读取效率。 - **使用`RandomAccessFile`**:这个类提供了更灵活的文件读写操作,允许随机访问文件的...
这将返回一个`Connection`对象,我们可以在这个对象上设置请求参数,如URL、请求方法等。 ```java Connection connection = Jsoup.connect("http://example.com"); ``` 2. **获取HTML文档**:使用`get()`或`...
int length = inputStream.read(buffer); String receivedData = new String(buffer, 0, length); // 处理接收到的数据... socket.close(); } catch (IOException e) { e.printStackTrace(); } ``` **二、...
- **`InputStream#read(byte[])`方法:**此方法用于读取一系列字节到字节数组中,返回实际读取的字节数,如果到达文件末尾则返回-1。 - **异常处理:**通过`try-catch-finally`结构来确保即使发生异常也能正确关闭流...
当我们需要从文件中读取数据时,可以使用`FileInputStream`类,它是`InputStream`的一个子类,专门用于读取文件内容。创建一个`FileInputStream`对象,只需要传入一个`File`对象即可: ```java File file = new ...
缓冲流的一个重要特性是可以使用`mark()`和`reset()`方法来标记和重置读取位置。此外,对于输出缓冲流来说,数据会先在内存中缓存,当调用`flush()`方法时,才会将缓存的数据立即写入。 #### 三、类层次结构 Java...
通常,这样的程序会创建两个字节流对象,一个用于读取源文件,另一个用于写入目标文件。 **字节流的基本类:** 在Java中,字节流的基类是`java.io.InputStream`和`java.io.OutputStream`。它们分别是所有输入和输出...