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

 更新时间:2016年06月27日 08:59:32   作者:skywangkw  
这里我们来看一下Java的DataInputStream和DataOutputStream数据输入输出流的使用示例,两个类分别继承于FilterInputStream和FilterOutputStream:

DataInputStream 
DataInputStream 是数据输入流。它继承于FilterInputStream。
DataInputStream 是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。
DataInputStream 函数列表:

DataInputStream(InputStream in)
final int  read(byte[] buffer, int offset, int length)
final int  read(byte[] buffer)
final boolean  readBoolean()
final byte  readByte()
final char  readChar()
final double  readDouble()
final float  readFloat()
final void  readFully(byte[] dst)
final void  readFully(byte[] dst, int offset, int byteCount)
final int  readInt()
final String  readLine()
final long  readLong()
final short  readShort()
final static String  readUTF(DataInput in)
final String  readUTF()
final int  readUnsignedByte()
final int  readUnsignedShort()
final int  skipBytes(int count)

示例代码:
关于DataInputStream中API的详细用法:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.lang.SecurityException;

/**
 * DataInputStream 和 DataOutputStream测试程序
 *
 * @author skywang
 */
public class DataInputStreamTest {

 private static final int LEN = 5;

 public static void main(String[] args) {
  // 测试DataOutputStream,将数据写入到输出流中。
  testDataOutputStream() ;
  // 测试DataInputStream,从上面的输出流结果中读取数据。
  testDataInputStream() ;
 }

 /**
  * DataOutputStream的API测试函数
  */
 private static void testDataOutputStream() {

  try {
   File file = new File("file.txt");
   DataOutputStream out =
     new DataOutputStream(
      new FileOutputStream(file));

   out.writeBoolean(true);
   out.writeByte((byte)0x41);
   out.writeChar((char)0x4243);
   out.writeShort((short)0x4445);
   out.writeInt(0x12345678);
   out.writeLong(0x0FEDCBA987654321L);

   out.writeUTF("abcdefghijklmnopqrstuvwxyz严12");

   out.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 /**
  * DataInputStream的API测试函数
  */
 private static void testDataInputStream() {

  try {
   File file = new File("file.txt");
   DataInputStream in =
     new DataInputStream(
      new FileInputStream(file));

   System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F));
   System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF));

   System.out.printf("readBoolean():%s\n", in.readBoolean());
   System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte()));
   System.out.printf("readChar():0x%s\n", charToHexString(in.readChar()));
   System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort()));
   System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt()));
   System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong()));
   System.out.printf("readUTF():%s\n", in.readUTF());

   in.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 // 打印byte对应的16进制的字符串
 private static String byteToHexString(byte val) {
  return Integer.toHexString(val & 0xff);
 }

 // 打印char对应的16进制的字符串
 private static String charToHexString(char val) {
  return Integer.toHexString(val);
 }

 // 打印short对应的16进制的字符串
 private static String shortToHexString(short val) {
  return Integer.toHexString(val & 0xffff);
 }
}

运行结果:

byteToHexString(0x8F):0x8f
charToHexString(0x8FCF):0x8fcf
readBoolean():true
readByte():0x41
readChar():0x4243
readShort():0x4445
readInt():0x12345678
readLong():0xfedcba987654321
readUTF():abcdefghijklmnopqrstuvwxyz严12

结果说明:
(1) 查看file.txt文本。16进制的数据显示如下:

201662785355523.jpg (717×79)

001f 对应的int值是31。它表示的含义是后面的UTF-8数据的长度。字符串“abcdefghijklmnopqrstuvwxyz严12”中字母“ab...xyz”的长度是26,“严”对应的UTF-8数据长度是3;“12”长度是2。总的长度=26+3+2=31。
(2) 返回byte对应的16进制的字符串
源码如下:

private static String byteToHexString(byte val) {
 return Integer.toHexString(val & 0xff);
}

想想为什么代码是:

return Integer.toHexString(val & 0xff);

而不是

return Integer.toHexString(val);

我们先看看 byteToHexString((byte)0x8F); 在上面两种情况下的输出结果。
return Integer.toHexString(val & 0xff); 对应的输出是“0xffffff8f”
return Integer.toHexString(val); 对应的输出是“0x8f”
为什么会这样呢?
原因其实很简单,就是“byte类型转换成int类型”导致的问题。
byte类型的0x8F是一个负数,它对应的2进制是10001111;将一个负数的byte转换成int类型时,执行的是有符号转型(新增位都填充符号位的数字)。0x8F的符号位是1,因为将它转换成int时,填充“1”;转型后的结果(2进制)是11111111 11111111 11111111 10001111,对应的16进制为0xffffff8f。
因为当我们执行Integer.toHexString(val);时,返回的就是0xffffff8f。
在Integer.toHexString(val & 0xff)中,相当于0xffffff8f & 0xff,得到的结果是0x8f。
(3) 返回char和short对应的16进制的字符串
“返回char对应的16进制的字符串”对应的源码如下:

private static String charToHexString(char val) {
 return Integer.toHexString(val);
}

“返回short对应的16进制的字符串”对应源码如下:

private static String shortToHexString(short val) {
 return Integer.toHexString(val & 0xffff);
}

比较上面的两个函数,为什么一个是 “val” ,而另一个是 “val & 0xffff”?
通过(2)的分析,我们类似的推出为什么 “返回short对应的16进制的字符串” 要执行“val & 0xffff”。
但是,为什么 “返回char对应的16进制的字符串” 要执行 “val” 即可。原因也很简单,java中char是无符号类型,占两个字节。将char转换为int类型,执行的是无符号转型,新增为都填充0。


DataOutputStream
DataOutputStream 是数据输出流。它继承于FilterOutputStream。
DataOutputStream 是用来装饰其它输出流,将DataOutputStream和DataInputStream输入流配合使用,“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。
示例代码
关于DataOutStream中API的详细用法:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.lang.SecurityException;

/**
 * DataInputStream 和 DataOutputStream测试程序
 *
 * @author skywang
 */
public class DataInputStreamTest {

 private static final int LEN = 5;

 public static void main(String[] args) {
  // 测试DataOutputStream,将数据写入到输出流中。
  testDataOutputStream() ;
  // 测试DataInputStream,从上面的输出流结果中读取数据。
  testDataInputStream() ;
 }

 /**
  * DataOutputStream的API测试函数
  */
 private static void testDataOutputStream() {

  try {
   File file = new File("file.txt");
   DataOutputStream out =
     new DataOutputStream(
      new FileOutputStream(file));

   out.writeBoolean(true);
   out.writeByte((byte)0x41);
   out.writeChar((char)0x4243);
   out.writeShort((short)0x4445);
   out.writeInt(0x12345678);
   out.writeLong(0x0FEDCBA987654321L);

   out.writeUTF("abcdefghijklmnopqrstuvwxyz严12");

   out.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 /**
  * DataInputStream的API测试函数
  */
 private static void testDataInputStream() {

  try {
   File file = new File("file.txt");
   DataInputStream in =
     new DataInputStream(
      new FileInputStream(file));

   System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F));
   System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF));

   System.out.printf("readBoolean():%s\n", in.readBoolean());
   System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte()));
   System.out.printf("readChar():0x%s\n", charToHexString(in.readChar()));
   System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort()));
   System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt()));
   System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong()));
   System.out.printf("readUTF():%s\n", in.readUTF());

   in.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 // 打印byte对应的16进制的字符串
 private static String byteToHexString(byte val) {
  return Integer.toHexString(val & 0xff);
 }

 // 打印char对应的16进制的字符串
 private static String charToHexString(char val) {
  return Integer.toHexString(val);
 }

 // 打印short对应的16进制的字符串
 private static String shortToHexString(short val) {
  return Integer.toHexString(val & 0xffff);
 }
}

运行结果:

byteToHexString(0x8F):0x8f
charToHexString(0x8FCF):0x8fcf
readBoolean():true
readByte():0x41
readChar():0x4243
readShort():0x4445
readInt():0x12345678
readLong():0xfedcba987654321
readUTF():abcdefghijklmnopqrstuvwxyz严12

相关文章

  • Spring Boot 中的 @EnableDiscoveryClient 注解的原理

    Spring Boot 中的 @EnableDiscoveryClient 注解

    @EnableDiscoveryClient 注解是 Spring Boot 应用程序注册到服务注册中心的关键注解,这篇文章主要介绍了Spring Boot 中的 @EnableDiscoveryClient 注解,需要的朋友可以参考下
    2023-07-07
  • SpringBoot浅析安全管理之高级配置

    SpringBoot浅析安全管理之高级配置

    安全管理是软件系统必不可少的的功能。根据经典的“墨菲定律”——凡是可能,总会发生。如果系统存在安全隐患,最终必然会出现问题,这篇文章主要介绍了SpringBoot安全管理之高级配置
    2022-08-08
  • SpringBoot处理接口幂等性的两种方法详解

    SpringBoot处理接口幂等性的两种方法详解

    接口幂等性处理算是一个非常常见的需求了,我们在很多项目中其实都会遇到。本文为大家总结了两个处理接口幂等性的两种常见方案,需要的可以参考一下
    2022-06-06
  • Java全面深入探究SpringBoot拦截器与文件上传

    Java全面深入探究SpringBoot拦截器与文件上传

    拦截器对使用SpringMvc、Struts的开发人员来说特别熟悉,因为你只要想去做好一个项目必然会用到它,文件上传是一个很常见的功能。在项目开发过程中,我们通常都会使用一些成熟的上传组件来实现对应的功能
    2022-05-05
  • Java获取指定父节点、子节点的方法实现

    Java获取指定父节点、子节点的方法实现

    在Java中,要获取指定节点的父节点和子节点,通常需要使用 DOM,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • 详解SpringBoot 处理异常的几种常见姿势

    详解SpringBoot 处理异常的几种常见姿势

    这篇文章主要介绍了详解SpringBoot 处理异常的几种常见姿势,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    这篇文章主要介绍了Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • spring注解@Service注解的使用解析

    spring注解@Service注解的使用解析

    这篇文章主要介绍了spring注解@Service注解的使用解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 为什么JDK8中HashMap依然会死循环

    为什么JDK8中HashMap依然会死循环

    这篇文章主要介绍了为什么JDK8中HashMap依然会死循环,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 安装elasticsearch-analysis-ik中文分词器的步骤讲解

    安装elasticsearch-analysis-ik中文分词器的步骤讲解

    今天小编就为大家分享一篇关于安装elasticsearch-analysis-ik中文分词器的步骤讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02

最新评论