`
liguanyi11111
  • 浏览: 62813 次
  • 性别: Icon_minigender_1
  • 来自: 黑龙江
社区版块
存档分类
最新评论

java读取文件(read与readFully)

 
阅读更多

          在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文件到byte数组的三种方法(总结)

    在Java编程中,有时我们需要将文件内容读取到内存中,以便进行进一步处理或传输。本文将介绍三种读取Java文件到byte数组的方法,供开发者参考。 ### 方法一:传统IO方式 这种方法是最常见的读取文件的方式,使用`...

    Java读取文件方法汇总

    例如,你可以使用`seek(long)`方法设置文件指针的位置,然后使用`read()`或`readFully()`方法进行读取。 总结: Java的I/O流库提供了丰富的文件读取方式,可以根据实际需求选择合适的方法。对于二进制文件,使用...

    多线程随机读取文件

    在Java编程中,多线程随机读取文件是一项重要的技术,尤其在处理大数据或高并发场景时。"RandomAccessFile"是Java中的一个类,它提供了对文件进行随机访问的能力,允许程序在文件的任意位置读写数据,而不仅仅是顺序...

    Alluxio java 客户端demo

    我们可以使用`ReadStream`的`read`方法读取文件内容,或者利用`readFully`一次性读取整个文件。注意,Alluxio支持块级别的缓存,所以多次读取同一文件可能会更快。 4. **文件删除** 删除Alluxio中的文件可以使用`...

    使用RandomAccessFie分段写大文件,创建多线程程席、通讨多线程分段读取大文件并分段写入到新文件

    3. **读取操作**:在`run()`方法内,使用`RandomAccessFile`的`seek()`方法移动指针到起始位置,然后使用`read()`或`readFully()`方法读取数据到缓冲区。 4. **写入操作**:读取到的数据写入到新文件,同样使用`...

    HDFS存取实例(java)

    2. **读取数据**:使用`FSDataInputStream.read()`或`FSDataInputStream.readFully()`方法读取数据。 3. **处理数据**:根据业务需求处理读取到的数据,例如将其写入本地文件。 4. **关闭流**:使用`...

    北大青鸟Java初级练习

    另一种更高效的方法是使用readFully()方法,它可以一次性读取整个文件内容并写入。 在"Object"开头的文件夹中,虽然具体需求没有详细说明,但我们可以猜测可能与对象的操作有关。可能是关于对象的创建、实例化、...

    Java软件开发实战 Java基础与案例开发详解 13-7 数据流 共6页.pdf

    根据给定文件的信息,我们可以提炼出关于Java软件开发中数据流相关的知识点,特别是针对`DataInputStream`类及其在文件和内存中的使用。 ### 13.7 数据流 #### DataInputStream 类 `DataInputStream`是Java中用于...

    RandFile.rar_Aglet

    在Java中,我们主要通过 `java.io` 包中的类来与文件进行交互。`File` 类用于表示文件和目录路径名的抽象表示,而 `RandomAccessFile` 类则提供了对文件的随机访问能力。与 `BufferedReader` 或 `FileInputStream` ...

    Java数据输入输出流.pdf

    它包含了多种方法,如readBoolean()用于读取一个布尔值,readInt()用于读取一个int型数值,readLine()用于读取一行文本,以及readFully()用于读取指定长度的字节数组。DataInputStream的创建通常需要一个已存在的...

    一步一步跟我学习hadoop(6)----hadoop利用FileSystem API 执行hadoop文件读写操作

    2. **读取数据**: 通过`FSDataInputStream`的`read()`方法读取字节,或者使用`readFully()`一次性读取整个文件。 ```java byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) !...

    Java对文件的随机读写以及压缩处理操作

    - `read()` / `readFully(byte[] b)`:读取单个字节或指定长度的字节数组。 - `length()`:获取文件的总长度。 例如,以下代码片段展示了如何向文件末尾追加数据: ```java RandomAccessFile myFile = new ...

    安卓系统通过NFC读取标签

    首先,打开一个`ParcelFileDescriptor`,然后创建一个`DataInputStream`,通过`read()`方法读取数据,并将其转换为16进制字符串。例如: ```java ParcelFileDescriptor pfd = tag.connectTag(); InputStream is = ...

    Android文件加密简单程序

    3. 读写:`read()`和`write()`系列方法用于读取和写入单个字节或字节数组。还有`readFully()`和`writeBytes()`等方法,适用于读写整块数据。 4. 关闭:操作完成后,记得调用`close()`方法关闭文件流,释放系统资源。...

    Java 中的 DataInputStream 介绍_动力节点Java学院整理

    它允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用 DataOutputStream(数据输出流)写入由 DataInputStream(数据输入流)读取的数据。 DataInputStream 的构造函数为 `...

    last指令的实现,开发项目实例

    通过`read()`或`readFully()`方法读取文件,根据utmp结构体的字节布局解析数据。 **5. 登录日志数据结构** 设计一个合适的Java数据结构(如类或接口)来存储登录日志信息,包括用户名、登录时间、主机名、终端类型...

    多线程和HTTP协议

    read.readFully(buf); out.write(buf, 0, len); out.flush(); read.close(); } else { // ...处理文件不存在的情况... } } // ...其他代码... } } } ``` 以上代码展示了如何使用Java实现一个多线程的...

    Android渠道打包工具packer-ng-plugin.zip

    解决方法由于使用Java直接写入和读取ZIP文件的注释都不可行,使用Python又不方便与Gradle系统集成,所以只能自己实现注释的写入和读取。 实现起来也不复杂,就是为了提高性能,避免读取整个文件,需要在注释的最后...

    Java的DataInputStream和DataOutputStream数据输入输出流

    此外,还有用于读取数组的`readFully()`和`skipBytes()`等方法。 下面是一个简单的`DataInputStream`使用示例: ```java import java.io.*; public class DataInputStreamExample { public static void main...

    mysql 异常com.mysql.jdbc.CommunicationsException

    “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 ...

Global site tag (gtag.js) - Google Analytics