开发者社区> 问答> 正文

java中 文件流中的 字节流读取一个字节的返回值是int:报错

在字节流中,读取一个字节返回的是一个int类型,但是一个int不是占4个字节吗,这个似乎相互矛盾a

展开
收起
kun坤 2020-06-07 20:03:14 1156 0
1 条回答
写回答
取消 提交回答
  • 摘抄:因为java读取read()方法时候,底层由c++实现,返回的是 unsigned byte ,取值范围为[0,255],而byte的取值范围是[-128,127], 那么[128, 255]就没有办法表示了,然后就会把byte升级为int,int就可以表示[128,255], 不过为什么不用short去接受返回呢???菜鸟求解

    ######回复 @快乐的一只小青蛙 : 糊涂之言,勿怪!!######回复 @kakai : short是C语言的基本类型之一。 C语言整形数据包括char、short、int、long######Java没有unsigned######

    对于你问题的具体回答 [详细描述]

    ######

    哪儿矛盾了,返回的int值表示读取的字节数,并不是读取到的字节

    ######可是,调用 public abstract int read() throws IOException,返回的是 0 到 255 范围内的 int 字节值。######

    摘要

    调用 read(), 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。
    调用 read(byte[] b), 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。

    1.    的确,public abstract int read()
                                      throws IOException

    输入流中读取数据的下一个字节。但是,返回的是 0 到 255 范围内的 int 字节值。一个字节能表示的最大的整数就是255(二进制11111111=十进制255)。所以,返回值的类型是 int。"
    read()的底层是由C++实现的,返回的是unsigned byte,取值范围为[0~255],在java中没有对应的类型,所以只能用int类型接收"。

    1. 中文字符,(至少)需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。类似的,日文和韩文等其他语言也有这个问题。为了统一所有文字的编码,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
    2. java 字符型变量,使用 UNICODE。UNICODE 通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0就可以。
    3. 比如,一个中文字符 '中', 对应的 Unicode 十进制编码是: 20013。于是,要读取 '中',就必须连续读入两个字节。按 UNICODE 编码,才能够将这两个二进制字节值"合成",将"合成"结果,成功转换成相应的中文字符。

    如下代码,详述通过 java 使用的 Unicode 编码 读取 中文字符的案例。

    1. 这里,通过建立一个 BigInteger 对象,获得 长度为2的字节数组 byte bete[]。
    2. 分别检查这两个字节的二进制表示, 即输出 每个字节元素的字节值,及其二进制表示。
    3. 从输出结果可以看出,将两个(整型)字节值 78( 二进制:01001110)   和 45( 二进制:00101101) 的二进制表示,“合成” 到一起,就是 字符'中' 的Unicode编码 20013, 即 0100111000101101(二进制) 。 
    import java.math.BigInteger;
    
    public class ByteArray1 {
      public static void main(String[] args) {
    	int zhong = (int)'中';
    	System.out.println( "字符 '"+ (char)zhong + "',其 UNICODE: " + zhong + "(十进制)");
    
    // 通过建立一个 BigInteger 对象,获得 长度为2的字节数组 byte bete[]。
    	BigInteger b = new BigInteger(String.valueOf(zhong));  
    	String zh = b.toString(2);
    	System.out.println( addZero(zh, 16) + "(二进制)" ); // 输出字符 '中' 的 二进制的字符串形式
    	
    	byte bete[] = b.toByteArray();//返回一个 byte 数组,该数组包含此 BigInteger 的二进制补码表示形式。
    	for (int j=0; j<bete.length ; j++){
    	byte bn = bete[j];
    	String str = Integer.toBinaryString(bn);      
    	System.out.println( bn + "( 二进制: " + addZero(str, 8) +  ")"); // 输出 每个字节元素的字节值的二进制表示
    		}		
    	}
    /* 将一个 整型 (16位) 或 字节(8位) 转化成 二进制表示的字符串时,
     * 若字符串长度不足 16位 或 8位 时,将空位补 0。
    */
      static String addZero(String s, int length){ 
    		String add="";
    		for(int k=0; k< ( length - s.length()); k++)
        	add += "0";
        	return add + s;        		
    	}
    }

    输出:

    字符 '中',其 UNICODE: 20013(十进制)
    0100111000101101(二进制)
    78( 二进制: 01001110)
    45( 二进制: 00101101)

    2.     如果调用 方法 
    public int read(byte[] b)
             throws IOException

    其功能是:"从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数"。注意,这时读取到的输入流的每个字节的值,依次存入缓冲区数组 b 的各个元素之中。

    结论:

    1. 调用 read(), 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。
    2. 调用 read(byte[] b), 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。
    3. 在字节流的基础上,加上编码,形成的数据流。字符流虽然以字节流为基础创建的,但是字节流可以支持声音,视频,图片,文本等所有文件类型,而字符流只支持文本文件。
    4. ASCII码:美国信息交换标准代码。单字节编码,不支持中文。
    5. Unicode/utf-8  :双字节编码,支持中文(万国码)。
    6. java 使用 Unicode。 

     

    参考:

    1. Java:InputStream中的read()返回int类型的疑问
    2. Java I/O(字节流、字符流与转换流)
    3. Java中字符流与字节流的区别
    ######

    引用来自“yong230”的评论

    哪儿矛盾了,返回的int值表示读取的字节数,并不是读取到的字节

    我也这样认为

    ######如果调用 方法 public int read(byte[] b) throws IOException 其功能是:从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。注意,读取到的输入流的每个字节值,依次存入缓冲区数组 b 的各个元素之中。调用 read(), 返回字节的值。######

    还有这么多人,居然方法的功能都不知道,, read和read(byte[])的功能都不同,

    2020-06-07 20:03:19
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载