在socket通信中,经常会有传送大量字节数组的时候,在一般情况下,直接用read(byte[] b)读取数组不会出现问题,但是当文件传输速度很快,或者量特别大的情况下。就可能导致传送的字节不完整。原因如下:
由于我们用的是基于TCP/IP的socket传输。发送端的数据首先进入缓存区被分割成TCP/IP报文,然后排队进入管道中,通过管道在进入接收端的缓存区进行排序再进入上层处理。由于数据在管道中的速度不同导致接收端的数据顺序根据tcp/ip协议需要重新排列。这时问题就来了,由于数据并不是按顺序一个个通过管道过来的,可能当一部分数据被传送过来,而还有数据并没有传输完毕。这时候使用read(byte[] b)去读写文件。这里请开jdk源码
public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i;
可以看出这里的read(byte[] b)是经过for循环然后read来达到读取整个数组的目的的。但是由于数据的分批到达的性质,可能在一段时间内数据没有及时到达,这是read()方法就会返回-1,而read(byte[] b)也就直接跳出了。所得到的byte数组也就没有完全写入,结果就丢失了一部分文件,继而后续也就都出现了错误。而解决方法可能有很多,这里先介绍一种简单的,可能后续再补充其他方法。使用dataInputStream中readFully(byte[] b)方法读取数组。看其源码:
public final void readFully(byte b[], int off, int len) throws IOException { if (len < 0) throw new IndexOutOfBoundsException(); int n = 0; while (n < len) { int count = in.read(b, off + n, len - n); if (count < 0) throw new EOFException(); n += count; } }
由源码可知,其中使用while循环判断byte数组是否已经读满所有数据,如果没有读满则继续读取补充直到读满为止,从而改善输入流出现空档,造成read方法直接跳出的问题。即通过缓冲来保证数量的完整,也算是常用的一种方法。所以以后若要读取特定长度的数据,使用readFully读取更加安全。
相关推荐
在Java编程中,有时我们需要将文件内容读取到内存中,以便进行进一步处理或传输。本文将介绍三种读取Java文件到byte数组的方法,供开发者参考。 ### 方法一:传统IO方式 这种方法是最常见的读取文件的方式,使用`...
例如,你可以使用`seek(long)`方法设置文件指针的位置,然后使用`read()`或`readFully()`方法进行读取。 总结: Java的I/O流库提供了丰富的文件读取方式,可以根据实际需求选择合适的方法。对于二进制文件,使用...
在Java编程中,多线程随机读取文件是一项重要的技术,尤其在处理大数据或高并发场景时。"RandomAccessFile"是Java中的一个类,它提供了对文件进行随机访问的能力,允许程序在文件的任意位置读写数据,而不仅仅是顺序...
我们可以使用`ReadStream`的`read`方法读取文件内容,或者利用`readFully`一次性读取整个文件。注意,Alluxio支持块级别的缓存,所以多次读取同一文件可能会更快。 4. **文件删除** 删除Alluxio中的文件可以使用`...
3. **读取操作**:在`run()`方法内,使用`RandomAccessFile`的`seek()`方法移动指针到起始位置,然后使用`read()`或`readFully()`方法读取数据到缓冲区。 4. **写入操作**:读取到的数据写入到新文件,同样使用`...
2. **读取数据**:使用`FSDataInputStream.read()`或`FSDataInputStream.readFully()`方法读取数据。 3. **处理数据**:根据业务需求处理读取到的数据,例如将其写入本地文件。 4. **关闭流**:使用`...
另一种更高效的方法是使用readFully()方法,它可以一次性读取整个文件内容并写入。 在"Object"开头的文件夹中,虽然具体需求没有详细说明,但我们可以猜测可能与对象的操作有关。可能是关于对象的创建、实例化、...
根据给定文件的信息,我们可以提炼出关于Java软件开发中数据流相关的知识点,特别是针对`DataInputStream`类及其在文件和内存中的使用。 ### 13.7 数据流 #### DataInputStream 类 `DataInputStream`是Java中用于...
在Java中,我们主要通过 `java.io` 包中的类来与文件进行交互。`File` 类用于表示文件和目录路径名的抽象表示,而 `RandomAccessFile` 类则提供了对文件的随机访问能力。与 `BufferedReader` 或 `FileInputStream` ...
它包含了多种方法,如readBoolean()用于读取一个布尔值,readInt()用于读取一个int型数值,readLine()用于读取一行文本,以及readFully()用于读取指定长度的字节数组。DataInputStream的创建通常需要一个已存在的...
2. **读取数据**: 通过`FSDataInputStream`的`read()`方法读取字节,或者使用`readFully()`一次性读取整个文件。 ```java byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) !...
- `read()` / `readFully(byte[] b)`:读取单个字节或指定长度的字节数组。 - `length()`:获取文件的总长度。 例如,以下代码片段展示了如何向文件末尾追加数据: ```java RandomAccessFile myFile = new ...
首先,打开一个`ParcelFileDescriptor`,然后创建一个`DataInputStream`,通过`read()`方法读取数据,并将其转换为16进制字符串。例如: ```java ParcelFileDescriptor pfd = tag.connectTag(); InputStream is = ...
3. 读写:`read()`和`write()`系列方法用于读取和写入单个字节或字节数组。还有`readFully()`和`writeBytes()`等方法,适用于读写整块数据。 4. 关闭:操作完成后,记得调用`close()`方法关闭文件流,释放系统资源。...
它允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用 DataOutputStream(数据输出流)写入由 DataInputStream(数据输入流)读取的数据。 DataInputStream 的构造函数为 `...
通过`read()`或`readFully()`方法读取文件,根据utmp结构体的字节布局解析数据。 **5. 登录日志数据结构** 设计一个合适的Java数据结构(如类或接口)来存储登录日志信息,包括用户名、登录时间、主机名、终端类型...
read.readFully(buf); out.write(buf, 0, len); out.flush(); read.close(); } else { // ...处理文件不存在的情况... } } // ...其他代码... } } } ``` 以上代码展示了如何使用Java实现一个多线程的...
解决方法由于使用Java直接写入和读取ZIP文件的注释都不可行,使用Python又不方便与Gradle系统集成,所以只能自己实现注释的写入和读取。 实现起来也不复杂,就是为了提高性能,避免读取整个文件,需要在注释的最后...
此外,还有用于读取数组的`readFully()`和`skipBytes()`等方法。 下面是一个简单的`DataInputStream`使用示例: ```java import java.io.*; public class DataInputStreamExample { public static void main...
“Communications link failure due to underlying exception: **BEGINNESTED EXCEPTION** java.io.EOFException STACK TRACE: java.io.EOFException at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1905) at ...