DataInputStream和DataOutputStream用法细节探讨

来源:互联网 发布:酷屏软件 编辑:程序博客网 时间:2024/05/22 17:08

http://blog.csdn.net/fishwjy/article/details/38092985

DataInputStream和DataOutputStream都是Java中输入输出流的装饰类,用起来很方便。今天就来讨论一下使用该类时候遇到的编码问题。

[java] view plaincopy
  1. package com.vincent.example;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8.   
  9. public class TestDataStream {  
  10.     public static void main(String[] args) {  
  11.         // 使用DataInputStream,DataOutputStream写入文件且从文件中读取数据。  
  12.         try {  
  13.             // Data Stream写到输入流中  
  14.             DataOutputStream dos = new DataOutputStream(new FileOutputStream(  
  15.                     "datasteam.txt"));  
  16.             dos.writeBytes("世界"); //按2字节写入,都是写入的低位  
  17.             dos.writeChars("世界"); // 按照Unicode写入  
  18.             // 按照UTF-8写入(UTF8变长,开头2字节是由writeUTF函数写入的长度信息,方便readUTF函数读取)  
  19.             dos.writeUTF("世界");   
  20.             dos.flush();  
  21.             dos.close();  
  22.   
  23.             // Data Stream 读取  
  24.             DataInputStream dis = new DataInputStream(new FileInputStream(  
  25.                     "datasteam.txt"));  
  26.             // 读取字节  
  27.             byte[] b = new byte[2];  
  28.             dis.read(b);  
  29.             System.out.println(new String(b, 02));  
  30.   
  31.             // 读取字符  
  32.             char[] c = new char[2];  
  33.             for (int i = 0; i < 2; i++) {  
  34.                 c[i] = dis.readChar();  
  35.             }  
  36.             System.out.println(new String(c, 02));  
  37.   
  38.             // 读取UTF  
  39.             System.out.println(dis.readUTF());  
  40.   
  41.             dis.close();  
  42.         } catch (IOException e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46. }  

使用16进制方式打开文件如下:

可以看出,第一个“世界”已经被截断,两个汉字都只被写入了低位,因此肯定乱码。

[java] view plaincopy
  1. package com.vincent.example;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8.   
  9. public class TestDataStream {  
  10.     public static void main(String[] args) {  
  11.         // 使用DataInputStream,DataOutputStream写入文件且从文件中读取数据。  
  12.         try {  
  13.             // Data Stream写到输入流中  
  14.             DataOutputStream dos = new DataOutputStream(new FileOutputStream(  
  15.                     "datasteam.txt"));  
  16.             dos.write("世界".getBytes()); // 按UTF8编码(我的系统默认编码方式)写入  
  17.             //dos.write("世界".getBytes("GBK"));  //指定其他编码方式  
  18.             dos.writeChars("世界"); // 按照Unicode写入  
  19.             // 按照UTF-8写入(UTF8编码长度可变,开头2字节是由writeUTF函数写入的长度信息,方便readUTF函数读取)  
  20.             dos.writeUTF("世界");   
  21.             dos.flush();  
  22.             dos.close();  
  23.   
  24.             // Data Stream 读取  
  25.             DataInputStream dis = new DataInputStream(new FileInputStream(  
  26.                     "datasteam.txt"));  
  27.             // 读取字节  
  28.             byte[] b = new byte[6];  
  29.             dis.read(b);  
  30.             System.out.println(new String(b, 06));  
  31.   
  32.             // 读取字符  
  33.             char[] c = new char[2];  
  34.             for (int i = 0; i < 2; i++) {  
  35.                 c[i] = dis.readChar();  
  36.             }  
  37.             System.out.println(new String(c, 02));  
  38.   
  39.             // 读取UTF  
  40.             System.out.println(dis.readUTF());  
  41.   
  42.             dis.close();  
  43.         } catch (IOException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47. }  

文件打开如下:


可以看出,读取前6字节并按照UTF-8解码就可以避免乱码。值得注意的是,String构造函数也可以指定对byte数组作其他编码方式的解码。例如:new String(b,0,6,"GBK")。同时使用writeUTF和readUTF可以免去程序猿对于长度的考虑,因为这两个函数为我们解决了长度问题,写入了文件,因此我们无需关心。但这样就使用了额外的空间去记录长度信息。

0 0