`
guojianhui0906
  • 浏览: 47768 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

对read(byte[] b)和readFully(byte[] b)的理解

阅读更多

要搞清楚read(byte[] b)和readFully(byte[] b)的区别,我从以下方面着手分析:

1.代码的具体实现

2.方法何时返回

3.字节是以什么方式在网络上传输的


1.read(byte[] b)调用read(byte[] b,0,b.length),其中的部分关键代码如下


Java代码 
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;  

  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;  


readFully(byte[] b)调用readFully(byte[] b,0,b.length),其中的部分关键代码如下


Java代码 
int n = 0;   
 while (n < len) {//该方法一直阻塞,直到读取到字节数据缓冲区装满   
     int count = in.read(b, off + n, len - n);   
     if (count < 0)   
         throw new EOFException();   
     n += count;   
 }   
  
//read(bytes[] b,int off,int len)中的关键代码   
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;  

       int n = 0;
        while (n < len) {//该方法一直阻塞,直到读取到字节数据缓冲区装满
            int count = in.read(b, off + n, len - n);
            if (count < 0)
                throw new EOFException();
            n += count;
        }

       //read(bytes[] b,int off,int len)中的关键代码
       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;  





2.从以上代码,我们可以看到,read(byte[] b)一直阻塞等待读取字节,直到字节流中的数据已经全部读完。而readFully(byte[] b)是当数据缓冲区的空间还有剩余时会阻塞等待读取,直到装满。


3.下图反映了字节流数据是如何通过网络的


应用程序用输出流将数据输入TCP的发送缓存中,这些数据被分割成TCP认为最适合发送的数据块(报文段或段)。报文段通过网络的传输到达指定地址(URL)的TCP接收缓存中,接收到的报文段很有可能不是顺序到达的,但TCP可以根据报文段的序号进行排序并存储在TCP接收缓存中。应用程序如果需要获得这些数据,需要通过输入流读取并解析这些报文段。


通过分析以上三个问题,我们可以解释以下代码存在的问题:


Java代码 
//发送端:   
OutputStream out = ......;//通过TCP连接得到输出流对象   
String content = "...";   
byte[] data = content.getBytes();   
output.write(data);   
int len = data.length;   
while (len++ < 30) {   
    output.writeByte('\0');//补够30个字节   
}   
//接收端:     
InputStream in = ......;//通过TCP连接得到输入流对象   
byte[] bytes = new byte[30];   
in.read(bytes);  

//发送端:
OutputStream out = ......;//通过TCP连接得到输出流对象
String content = "...";
byte[] data = content.getBytes();
output.write(data);
int len = data.length;
while (len++ < 30) {
	output.writeByte('\0');//补够30个字节
}
//接收端:	
InputStream in = ......;//通过TCP连接得到输入流对象
byte[] bytes = new byte[30];
in.read(bytes);  


由于字节数据是在网络中通过TCP连接进行传输,这些数据刚刚到达接收端(存储在TCP接收缓冲区)的可能只是其中的一部分数据,其他的数据可能还在传输中甚至在发送端的TCP缓存中。在调用read(byte[] b)读取数据时,b中得到的就是发出的30个字节的一部分。

要想完全获得这30个字节数据,合理的方法是用readFully(byte[] b)读取,因为该方法会一直阻塞等待,直到30个数据全部到达(数据缓冲区装满)

  • 大小: 36 KB
分享到:
评论

相关推荐

    读取Java文件到byte数组的三种方法(总结)

    `RandomAccessFile`提供了对文件的随机访问能力,可以用来读取文件内容到byte数组。 ```java public byte[] readFileByRandomAccessFile(String filePath) throws IOException { File file = new File(filePath); ...

    如何有效的使用C#读取文件

    public static byte[] ReadFully(Stream stream) { byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()) { while (true) { int read = stream.Read(buffer, 0, buffer.Length); ...

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

    - `public final void readFully(byte[] b)`:从当前数据输入流中读取b.length个字节到该数组。 - `public final void readFully(byte[] b, int off, int len)`:从当前数据输入流中读取len个字节到该字节数组。 - `...

    c#读取文件详谈

    在C#编程中,读取文件是一项基本操作,而.NET框架...对于初学者来说,理解这些基础概念和技巧非常重要,因为它们是构建复杂应用程序的基础。在实际开发中,根据需求选择合适的方法,可以有效提高代码的效率和可靠性。

    HTTP SPDY客户端开发包okhttp.zip

    示例代码: OkHttpClient client = new OkHttpClient();... byte[] response = readFully(in); return new String(response, "UTF-8"); } finally { if (in != null) in.close(); } } 标签:okhttp

    安卓系统通过NFC读取标签

    总之,Android系统通过NFC读取非NDEF格式的16进制数据涉及对NFC技术的理解,以及自定义数据解析。利用Eclipse进行开发时,正确配置权限、监听NFC事件、读取原始数据并进行16进制转换是关键步骤。这样的应用可以实现...

    RandFile.rar_Aglet

    `File` 类用于表示文件和目录路径名的抽象表示,而 `RandomAccessFile` 类则提供了对文件的随机访问能力。与 `BufferedReader` 或 `FileInputStream` 不同,`RandomAccessFile` 允许我们直接定位到文件的任意位置...

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

    DataInputStream 的 `readFully(byte b[])` 方法可以从输入流中读取数据并填满字节数组 b 中。该方法可以重复读取直到填满字节数组 b。 DataInputStream 是 Java 中一个非常重要的输入流类,它提供了许多方法来读取...

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

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

    多线程和HTTP协议

    #### 一、多线程概念及应用 **多线程**是计算机程序设计中的一个重要概念,它允许在...以上代码展示了如何使用Java实现一个多线程的HTTP服务器,通过对HTTP协议的理解和多线程技术的应用,实现了基本的文件服务功能。

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

    注释包含Comment Length和File Comment两个字段,前者表示注释内容的长度,后者是注释的内容,正确修改这一部分不会对ZIP文件造成破坏,利用这个字段,我们可以添加一些自定义的数据,PackerNg项目就是在这里添加和...

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

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

    Java读取文件方法汇总

    在示例代码中,`read()`方法被用来一次读取一个字节,而`read(byte[])`则用于一次读取多个字节。需要注意的是,当文件末尾到达时,`read()`方法会返回-1。 2、**按字符读取文件内容** 当处理包含文本的文件,如源...

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

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

Global site tag (gtag.js) - Google Analytics