调用ByteBuffer.getInt()方法遇到的奇怪错误

最近在参加阿里的中间件比赛,中间用到了RocketMQ的思想,并且主要集中在使用NIO来读写文件。其中遇到了一个很蛋疼的问题,想了半天想不出来为什么,现已解决并来记录一下。

先上代码:

@Test
public void test() throws IOException {
FileChannel fc = new RandomAccessFile(STORE_PATH, "rw").getChannel();
ByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
int a = byteBuffer.getInt();
System.out.println(a);
}

代码主要使用了Java NIO中的FileChannel和ByteBuffer,目的是读取文件中的四个字节,并将其转为int类型的数字,对于这个文件我手动输入了四个'0',按照我的想法,读出来应该还是会为0。然而结果却如下:

808464432

这是个什么鬼?试了几次都是一样的数字,觉得很奇怪,为什么不是0呢。看了下ByteBuffer.getInt()的源码,发现ByteBuffer是一个抽象类,该方法有两种实现方式,分别是DirectByteBuffer和HeapByteBuffer,其中NIO使用的DirectByteBuffer,所以看下源码:

private int getInt(long a) {
if (unaligned) {
int x = unsafe.getInt(a);
return (nativeByteOrder ? x : Bits.swap(x));
}
return Bits.getInt(a, bigEndian);
} public int getInt() {
return getInt(ix(nextGetIndex((1 << 2))));
}

其中调用的是Unsafe包下的getInt()的native方法,好像又遇到死胡同了。

最后没招了,突发奇想搜了一下808464432这个数字,搜到

int变量的值为808464432 是为什么?内存越界?被赋错值?这篇博客,其中的一段话很明确的解释了原因:

808464432,是10进制数,转换为16进制是0x30303030,0x30是字符'0'的ASCII码的16进制表示,也就是说,808464432这个数字,对应字符串“0000”,一个int变量,占4个字节,如果每个字节都写入一个字符'0',那么就会是这个数。

原来是因为我输入的时候是以字符形式输入到文件,稍微修改一下代码,果然就好了,代码和结果如下:

@Test
public void test() throws IOException {
FileChannel fc = new RandomAccessFile(STORE_PATH, "rw").getChannel();
ByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
byteBuffer.putInt(0,1);
int a = byteBuffer.getInt();
System.out.println(a);
}

【Java学习】调用ByteBuffer.getInt()方法得到808464432的更多相关文章

  1. Java学习-026-类名或方法名应用之二 -- 统计分析基础

    前文讲述了类名或方法的应用之一调试源码,具体请参阅:Java学习-025-类名或方法名应用之一 -- 调试源码 此文主要讲述类名或方法应用之二统计分析,通过在各个方法中插桩(调用桩方法),获取方法的调 ...

  2. Java学习-025-类名或方法名应用之一 -- 调试源码

    上文讲述了如何获取类名和方法名,敬请参阅: Java学习-024-获取当前类名或方法名二三文 . 通常在应用开发中,调试或查看是哪个文件中的方法调用了当前文件的此方法,因而在实际的应用中需要获取相应的 ...

  3. JAVA如何调用C/C++方法

    JAVA如何调用C/C++方法 2013-05-27 JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能.解决JAVA对本地操作的 ...

  4. java学习笔记5--类的方法

    接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...

  5. java学习之创建线程方法二

    我们上一节当中讲到了创建线程的第一种方法,就是继承Thread类,覆写Thread当中的run方法,然后创建子类对象,之后调用对象的start方法启动线程.但是这种方法有一个缺陷,因为我们知道在jav ...

  6. Java动态调用类中方法

    在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...

  7. 【Android】java中调用JS的方法

    最近因为学校换了新的教务系统,想做一个模拟登陆功能,发现登陆的账号和密码有一个js脚本来进行加密 整理了一下java中执行JS的方法 智强教务 账号 密码 加密方法 var keyStr = &quo ...

  8. Java学习笔记4(方法)

    方法和c++中的函数类似,区别在于java的方法定义不限位置,而c++中的定义在主函数后面的函数调用前要声明: 求矩形面积方法示例: public class MethodDemo{ public s ...

  9. Java学习之==>常用字符串方法

    1.定义字符串 // 定义, 为初始化 String str1; // 定义, 并初始化为null String str2 = null; // 定义, 并初始化为空串 String str3 = & ...

随机推荐

  1. hdu 2121 Ice_cream’s world II

    Ice_cream’s world II http://acm.hdu.edu.cn/showproblem.php?pid=2121 Time Limit: 3000/1000 MS (Java/O ...

  2. UIWebView---iOS-Apple苹果官方文档翻译

    CHENYILONG Blog UIWebView---iOS-Apple苹果官方文档翻译 UIWebView 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博h ...

  3. 用C++写一个没人用的ECS

    github地址:https://github.com/yangrc1234/Resecs 在做大作业的时候自己实现了一个简单的ECS,起了个名字叫Resecs. 这里提一下一些实现的细节,作为回顾. ...

  4. 安装 Google BBR 加速VPS网络

    Google BBR就是谷歌公司提出的一个开源TCP拥塞控制的算法.详情可以看这儿:https://lwn.net/Articles/701165.https://blog.sometimesnaiv ...

  5. ASLR

    @author:dlive ASLR address space layout randomization 微软从windows vista/windows server 2008(kernel ve ...

  6. 【Python学习】字符编码

    先说两个基础知识. (1)计算机内部,数据是由0,1组成的: (2)计算机最小的数据单位,就是一个二进制单位即bit,接下来就是8个二进制单位表示一个字节(Byte). 1 ASCII码 ASCII码 ...

  7. 用VIM查看编辑二进制文件

    用VIM查看编辑二进制文件 vim可以很方便地编辑二进制文件,个人认为它比emacs的二进制编辑方式更好用.vim中二进制文件的编辑是先通过外部程序xxd来把文件dump成其二进制的文本形式,然后就可 ...

  8. 无状态Http

    无状态的根本原因 浏览器和服务器使用socket通信,服务器将请求结果返回给浏览器后,会关闭当前socket连接.而且服务器会在处理页面完毕后销毁页面对象. 应用层面的原因 浏览器和服务器之间通信都遵 ...

  9. ansible command模块将返回值写入变量

    ansible 中command模块支持 register参数将远程命令执行的输出结果存储在变量中,后续可以在when中对该变量进行检索确定下一步任务. --- - name: cat /etc/re ...

  10. 大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理(转)

    原文链接:http://op.baidu.com/2015/04/https-s01a01/ 1 前言 百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS.本 ...