繁体   English   中英

为什么 write() 和 read() 似乎写入和读取超过一个字节?

[英]Why do write() and read() appear to write and read more than a byte?

Java ,一个byte可以容纳的最大值是 127,也就是 8 位。 此外, FileInputStream使用的 read() 方法(它继承自InputStream )声明它只读取一个byte ,而FileOutputStream使用的 write() 方法(它继承自OutputStream )声明它只写入一个byte 但是,当我将一个大于 127 但小于 256 的数字传递给 write() 然后 read() 它时,我得到一个十进制值确实在 127 和 255 之间的字符。这似乎表明 write() 可以实际上写入 9 位而不是 8,而 read() 实际上可以读取 9 位而不是 8。所以,我的问题是这怎么可能? read() 如何读取多于一个byte而 write() 如何写入多于一个byte 还有什么我想念的吗?

再举一个例子,假设我将整数 1000 传递给 write()。 write() 然后输出一个字符,然后 read() 读取为十进制值 232。这似乎是因为 1000 - 512 - 256 = 232,这似乎再次表明 write() 和 read() 写入和读取 9 位(最多 255)而不是一个字节(8 位,最多 127)。 在我看来,write() 正在写入 1000 的低 9 位,然后 read() 读取,在这种情况下给出 232。

我已经发布了我用来测试这一切的程序。 另外,我对Java还很Java ,所以非常感谢任何帮助或想法!

import java.io.*;

public class TestingCharsAndBytes 
{

    public static void main(String[] args) 
    {

        FileOutputStream output = null;
        FileInputStream input = null;       
        try
        {
            output = new FileOutputStream(".../testFileIO1.txt");
            input = new FileInputStream(".../testFileIO1.txt");

            // Stuff to try:


            doFileResult(512,output,input);
            doFileResult(128,output,input);
            doFileResult(256,output,input);
            doFileResult(257,output,input);
            doFileResult(160,output,input);
            doFileResult(289,output,input);
            doFileResult(1000,output,input);
            doFileResult(2000,output,input);            
        }
        catch(IOException e)
        {
            System.out.println("Error occurred.");
            e.getStackTrace();
        }
        finally
        {
            try
            {
                output.close();
                input.close();
            }
            catch(Exception e)
            {
                System.out.println("Error closing file.");
            }           
        }
    }   
    public static void doFileResult(int toWrite, FileOutputStream outStream, FileInputStream inputStream) throws IOException
    {
        System.out.println("******************");
        outStream.write(toWrite);

        int x = inputStream.read();
        char y = (char) x;

        System.out.println("Integer passed to write: " + toWrite);
        System.out.println("Input integer read: " + x);
        System.out.println("Input character read (after casting to char): " + y);
        System.out.println();       
    }
}

根据文档read()使用-1作为特殊值来表示EOF。 如果使用字节的实际范围(-128..127),则-1为有效字节。

如基本方法的文档InputStream.read()

值字节以int形式返回,范围为0到255。如果由于到达流的末尾而没有字节可用,则返回值-1。

从流中读取代码的惯用方式是:

while (true) {
  int v = stream.read();
  if (v == -1) {
    break;
  }
  byte b = (byte) v;
  // Do something.
}

强制转换为字节将“正确”映射int 0..255到字节-128..127,因为将范围从32位缩小到8位将仅保留8个最低有效位。

但是,当我将大于127但小于256的数字传递给write()然后再进行read()时,我得到的字符的十进制值确实介于127和255之间。这似乎表明write()可以实际上写9位而不是8位,而read()实际上可以读9位而不是8位。

那是不对的。

字节有8位,因此它可以保存0255的值(包括0255 但是,字节是带符号的,因此一个字节可以容纳的largest positive127 ,需要7位。 最小的是-128 ,占用8位。 因此,根据它们的打印方式,您可以获得有符号或无符号的值。

这是一个例子。

      byte d = (byte) (255); // -1
      System.out.println(d);
      d = (byte) (128); // -128
      System.out.println(d);

从数组中写入两个字节,然后分别读取它们。

      byte[] b = { 125, 127
      };
      output.write(b);
      int inbyte = input.read();
      System.out.println(inbyte); //125
      inbyte = input.read();
      System.out.println(inbyte); // 127



      // writing using an int.
      int large = (102 << 8 | 254);
      output.write(large);
      int byt = input.read(); // writes lower byte of large
                              // which would be 254
      System.out.println(byt);
      System.out.println((byte) byt); // casting to a byte yields -2.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM