Java 从流中读取byte的奇怪现象,出现负值,详解(经典 重要)

告别单调!3种方法给VS2019换上VSCode同款NightOwl主题(附字体优化技巧) 本文详细介绍了三种将VSCode热门NightOwl主题移植到VS2019的方法,包括扩展市场直装、官方主题库导入与增强以及手动调色实现像素级复刻。同时提供了字体优化与视觉增强技巧,帮助开发者打造更舒适的编码环境。 阅读详情

来源:https://blog.youkuaiyun.com/xingtanzjr/article/details/50898122

https://blog.youkuaiyun.com/zhaomengszu/article/details/54562056

其实一点都不奇怪,下面我们来详细分析

首先看下面一段代码,代码的意思是将128写入到文件中,再从文件中读出一个byte输出

    File f = new File("f1");
    FileOutputStream fos = new FileOutputStream(f);
    fos.write(128);
    fos.close();

    FileInputStream fis = new FileInputStream(f);
    int a = fis.read();
    System.out.println(a);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出结果为:

128

这符合我们的直观感觉,写入128,读出来也是128

下面我们修改一下代码,将数据度入到byte数组里,看看输出会是什么样子,代码如下

    File f = new File("f1");
    FileOutputStream fos = new FileOutputStream(f);
    fos.write(128);
    fos.close();

    FileInputStream fis = new FileInputStream(f);
    byte[] b = new byte[1];
    fis.read(b, 0, 1);
    System.out.println(b[0]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

输出结果为

-128

好了,“奇怪”的现象出现了,这是为什么呢?

首先,我们需要了解一些基础知识,在Java中,byte的范围为 -128 ~ 127,并没有128这个数值;其次,读者需要了解一下负数在Java中如何表示(即原码、反码、补码的相关知识,请读者自行谷歌)。

下面,我们来分析一下出现 -128 的原因:

首先,fos.write(128) 表示写入 “128” 所代表的字节,即 1000 0000,也就是说,文件中当前包含一个字节,8位依次为 1 0 0 0 0 0 0 0

当我们调用fis.read()时,该方法会返回一个无符号byte,也就说直接将1000 0000翻译为128,大家可以去看该方法的说明,返回值的范围为0 ~ 255;所以我们得到了 128 的输出;

当我们调用fis.read(b, 0, 1)时,相当于把文件中第一个字节读入到了b[0]中,此时b[0]的二进制表示为1000 0000,根据负数在Java中的表示方法,我们可以计算出,该二进制序列的数值为 -128,也就是说这个过程并没有将其转化为无符号数值的过程,所以我们得到了 -128 的输出。

那么,我们如何解决这个问题呢?

首先,我们需要看一下fos.write(int a)这个方法,它的功能是写入a代表的byte值,也就是说,该函数实际上是将a 的后八位写入到文件中 , 所以作者建议在使用该方法时,为了避免产生歧义,a 的范围最好在 0 ~ 255 之间,初学者最好在 0 ~ 127 之间。(具体原因可以结合负数的表示规则自己想想哦~)。

回归正题,我们如何解决上文中的问题呢,即 “写入128、读出-128” 的问题,我们可以用下面的代码来解决。

    File f = new File("f1");
    FileOutputStream fos = new FileOutputStream(f);
    fos.write(128);
    fos.close();

    FileInputStream fis = new FileInputStream(f);
    byte[] b = new byte[1];
    fis.read(b, 0, 1);
    System.out.println(b[0] & 0xff);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

也就是说,用b[0] & 0xff的方法得到b[0]的无符号值。

插入一个小问题,就是,b[0] | 0xff得到的是一个负值,而 & 得到的却是一个正值。这里根据作者的猜测,可能是如下原因,主要和 & 运算的步骤有关:

进行 b[0] & 0xff运算时的步骤如下:

  1. 因为0xff默认应该用int来保存,所以首先将 b[0] 强制转化为 int 类型表示,b[0] 的数值为-128,所以其二进制表示为11111111 11111111 11111111 10000000
  2. 0xff的二进制表示为 00000000 00000000 00000000 11111111
  3. 这两个数做 & 运算后,得到 00000000 00000000 00000000 10000000,其表示的值为128

“或 运算”的过程类似,读者可以自己推理一下

Halcon异常检测训练避坑指南:如何避免GPU内存溢出和样本不足问题 本文针对Halcon深度学习异常检测训练中常见的GPU内存溢出和样本不足两大难题,提供了从原理分析到实战解决方案的深度指南。通过调整批次大小、图像尺寸、使用梯度累积等技巧有效管理显存,并利用针对性数据增强与人工合成策略破解小样本困境,帮助开发者构建稳定高效的训练流程。 阅读详情

相关推荐

ArcMap实战:用栅格计算器搞定16年NDVI趋势分析,附完整F检验流程

本文详细介绍了如何使用ArcMap的栅格计算器进行16年NDVI趋势分析,包括数据预处理、线性趋势计算和F显著性检验的全流程操作。通过实际案例和统计原理解析,帮助GIS从业者掌握植被覆盖变化的分析方法,特别适合生态评估和农业监测应用。

weixin_29251567的博客 252

Java 从流中读取byte的奇怪现象,出现负值,详解

其实一点都不奇怪,下面我们来详细分析 首先看下面一段代码,代码的意思是将128写入到文件中,再从文件中读出一个byte输出 File f = new File("f1"); FileOutputStream fos = new FileOutputStream(f); fos.write(128); fos.close(); FileInputStream

xingtanzjr的博客 8644

数理金融学笔记 Chap2 二叉树模型Binomial

2 二叉树模型与期权定价 Binomial Model and Option Pricing 文章目录2 二叉树模型与期权定价 Binomial Model and Option Pricing单期二叉树模型 One-step Binomial Model风险与无风险资产单期二叉树模型与无套利条件无套利定价 No Arbitrage Pricing风险中性定价 Risk Neutral PricingDelta套期保值 Delta Hedging两期二叉树模型 Two-Step Binomial Model

weixin_66831131的博客 2387

谈谈java中字节byte有负数的现象

在研究编码时,无意中发现java中输出编码后的字节数据的值有的是负值,比如utf-8编码后的字节数据,通过遍历,打印都是负值,java中字节byte有负数的现象让我产生了兴趣,在此探讨一下。 关于编码的字节有负数的现象,可以参考这篇博客: http://blog.youkuaiyun.com/csdn_ds/article/details/79077483 下面我用java中的数据流去说说这个现象。

默默前行,勿喜、勿悲、一切随缘! 3万+

在 CentOS7 下安装 Cadence IC验证平台 INCISIVE152

前言 本文所使用的软件 虚拟机软件:VMware Workstation 15 PRO 如何安装? 操作系统:CentOS-7, CentOS-7-x86_64-DVD-1810.iso 如何安装? 简介 INCISIVE Incisive是nc_verilog, nc_sim, nc_lauch,以及ABV,TBV的集合,用于仿真和验证。 InstallScape InstallSc...

沈醉不知的博客 2万+

Windows打印体系结构之Windows内置打印驱动程序

时间是一种很残酷的东西,它只会冲淡能够冲淡的,但也会洗尽铅华帮你留下该留下的。1.3.4、Windows内置打印驱动程序现在的Windows下的打印机驱动程序通常分为V4打印机驱动程序(V4 Printer Driver)、XPS打印机驱动程序(XPSDrv)、微软通用打印机驱动程序(Microsoft UniversalPrinter Driver)、微软PostScri...

weixin_34309435的博客 2253

netty读取基本类型出现负数 读取原始报文并打印

netty读取基本类型出现负数

weixin_45623983的博客 530

SolidWorks + AI:利用 DeepSeek AI 自动生成 VBA Macro 宏,实现智能化建模!

本教程介绍如何将集成到插件,实现的自动化操作。通过 DeepSeek AI,您可以快速生成高效的,提升!💡。

SolidWorksAPI的专栏 1万+

JAVA中byte为负数处理

java中一定有人遇见过byte取值为负数情况,比如0xc0对应的值-64,其实应该是192,这里就需要我们转化处理 /** * Description: 负数byte转正int * */ public static Integer byteToInteger(Byte b) { return 0xff & b; } ...

巴韭特 万手哥的博客 3314

大模型之Spring AI实战系列(二):Spring Boot + OpenAI 打造聊天应用全攻略

本篇文章是《Spring AI实战》专栏的第一篇开发入门文章,我们将借助一个完整的OpenAI聊天应用示例,详细介绍如何运用Spring Boot和Spring AI快速搭建一个支持OpenAI API的聊天服务,全面涵盖基础对话、流式对话、多提供商配置等核心功能。

寻道AI,探索AI无限可能! 6855

18 中望CAD二次开发-DWG参照(ZRX C++)

本文介绍了CAD参考外部dwg文件的原理和代码实现及如何卸载参考文件的全过程,是中望CAD二次开发中重要的功能。

cilvsuanna的博客 205

java字节流的-1和读取强制转为byte的问题

java中inputstream是所有字节输入流的父类,理解时要注意每次 read()的时候返回的都是一个 0~255的整数刚好代表了一个字节的意思。但是int是四位的,当我们强制转为byte的时候,由于java采取的是暴力的截断,因而只会取低位字节。因而这时byte(-128~127)就可能是负数了。当我们再有byte转位int的时候,这时候这个int可能就不等于read出来的int。例如: ...

z3111001358的博客 1318

华为OD机试真题 新系统2026-04-01 C语言 实现【计算数列位置N的值】

1、输入M、N两个数,则按照以下规则形成一个数列; 2、数列的前M个元素的值为1到M; 3、从M+1个元素开始,计算的逻辑为: 如果其前面的M个元素中,存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之如果其前面的M个元素中,不存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之差;

MISAYAONE的博客 588

关于Java溢出

回顾一下上课的小实验: 首先写下如下代码: 首先定义了一个Demo类,然后定义了byte类型的a变量,初始化a的变量值为127,(已知byte类型的范围为-128-127),没有越线,然后输出a。 编译没错,得出答案为127,完美。 然后我们给a赋值为a+1; 但是,error。 他告诉我们cannot convert from int to byte 翻译为不能从int转换为...

Leondon的博客 1017

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C语言快速入门——基础语法、指针与内存管理笔记

重点阐述了C语言的基本程序结构、编译运行环境配置方法,以及数据类型分类(基本类型、枚举、void和派生类型),特别说明了整数类型在不同平台下的差异和浮点类型的标准规范。最后提及void类型在函数返回、参数传递和指针应用中的关键作用。

fancyfor的博客 573

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

java中int类型强制转换成byte类型出现负数输出问题

原码: 11101010 -> -(2 + 8 + 32 + 64) = -106。补码: 10010110 (由于最高位是1,计算机以为该数为一个负数).这个问题就与计算机底层的存储原理有关了.计算机存储数据在内存中是以补码的形式进行存储的.正数的原码,反码,补码相同. 而负数的补码为原码按位取反,末位加1.反码: 10010110。反码: 11101001。150的原码: 10010110。

m0_72926194的博客 806

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java 负数 字节,Java AudioInputStream如何支持负数字节跳过

我正在尝试使用AudioInputStream跳过负数的字节skip(long bytes)方法.问题是试图(假设有少量字节…):int skipped = audioInputStream.skip(-bytes);始终如回答Java AudioInputStream skip with negative number of bytes always returns 0所述返回0我需要创建一个实...

weixin_39962675的博客 202

为什么在java中文转bytes是负数

import java.util.Arrays; public class Test { public static void main(String[] args) { // 将中字转换成byte数组 byte[] bytes = "中".getBytes(); System.out.println(Arrays.toString(bytes)); // 输出[-28, -72, -83] } } 为什么中文的中转换成byte类..

q513485326的博客 1153

Java的字节(byte)数组与Python3中的字节类型负值问题

在Java中,字节数组可以存放负值,这是因为Java的byte类型的取值范围为-128到127之间,而在Python3中,bytes的取值范围为0到256。此时如果需要通过Python3来实现同样的加密算法则会出现一个问题,就是上面Java代码中的负值无法在Python3中直接表示。之后在传入Python中对应的AES算法函数当中,相应的加密结果便一致了。

程序新视界 1442

java 负数 字节_java byte 字节负数

由于通讯协议中长度使用byte字节来表示,但在java中长度超过127的时候会变成负数,所以需要保证得到的长度是正数byte b& 0xFFhttp://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html在剖析该问题前请看如下代码public static String bytes2HexString(byte[] b) ...

weixin_30709043的博客 929

关于FileInputStream中read返回值范围问题

在FileInputStream中,read返回值的范围是: 因为ASCII码的取值范围是-1 - 255,因此范围是-1 - 255

Funny_Ma的博客 2859

java 字节 负数_java 中文 字符对应的byte 为什么是负数。。二进制 到 16进制

暂存还没有搞明白一个字节占8位,可以表示 00000000-11111111 , 其中首位为符号位,也就是说能表示【-128--127】之间。为什么是8位,因为英文中256已经能够包含所有字符了。但是这样的话,其他国家的文字没法表示了,所以发明了utf-8国际统一编码,基本可以表示世界上所有字符了。而中文也有专门的编码GBK,一个字符占2个字节,就是16位,编码定义第一个字节从129开始,第二个字...

weixin_39915204的博客 880

java对byte数组解压缩(zip,gzip,bzip2,jzlib)

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPO

majian_1987的专栏 1万+

java byte数组异或校验时出现负数问题

简介 最近由于需要对接校园的刷卡机支付,协议需要用到异或校验。参照校验的流程对相邻数组进行异或,得出的结果却与示例的不一样,而且还是负数。 起先以为自己的算法或者数据有问题,但是检查了一遍后还是一样。 分析原因 由于协议中有字段表示的数值大于127,如协议中该字段16进制为0XA2,本来数值应该是162,结果转变成byte时变成了-94,异或校验后该字段的数值变为了负数,导致异或校验的...

王明海的专栏 3440

java byte 操作_Java byte数组操纵方式代码实例解析

字节数组的关键在于它为存储在该部分内存中的每个8位值提供索引(快速),精确的原始访问,并且您可以对这些字节进行操作以控制每个位。 坏处是计算机只将每个条目视为一个独立的8位数 - 这可能是你的程序正在处理的,或者你可能更喜欢一些强大的数据类型,如跟踪自己的长度和增长的字符串 根据需要,或者一个浮点数,让你存储说3.14而不考虑按位表示。 作为数据类型,在长数组的开头附近插入或移除数据是低效的,因为...

weixin_29548281的博客 658

Java网络编程中的字节流传输时输出为负数输出读取却为正数

在使用socket编程时,发现服务端通过字节输出流输出一个负数,而客户端读入的却是一个正数。比如-1变成了255,-128变成了128,-126变成了130

yq15797688367的博客 1597
上一篇: byte为什么要与上0xff?
下一篇: Vue —— 使用 vue-cli 搭建项目
周末去看海
博客等级 码龄9年 50粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值