黑马程序员42,基本数据操作流,字节数组操作流,转换流,编码表

----------- android培训java培训、java学习型技术博客、期待与您交流!------------ 

黑马程序员42,基本数据操作流,字节数组操作流,转换流,编码表  

一:基本数据操作流----》

        DataInputStream基本数据读取流,构造函数是:

public   DataInputStream(InputStream in)   //指定某个读取流建立DataInputStream类的对象

比较常见的方法如下:

public  final  int  read(byte[]b) throws  IOException   //按照数组读取数据

public  final  int  read(byte[]b, int off, int len) throws  IOException   //按照装进数组里数据的有效位数来读取数据

public  final  boolean  readBoolean()throws  IOException//读取一个boolean数据

public  final  byte  readByte()throws IOException //读取1个字节解释为一个byte数据

public  final  char  readChar()throws IOException  //读取2个字节解释为一个char数据

public  final  double  readDouble()throws IOException //读取8个字节解释为一个double数据

public  final  float  readFloat()throws IOException //读取4个字节解释为一个float数据

public  final  int  readInt()throws IOException//读取4个字节解释为一个int数据

public  final  long  readLong()throws IOException//读取8个字节解释为一个long数据

public  final  short  readShort()throws IOException//读取2个字节解释为一个有符号的16为数

        这一类的方法还有很多,这里就不必多说了,可以总结出一点的是,不同写入格式是按照不同位数读取的


       DataOutputStream基本数据读取流,构造函数是:

public  DataOutputStream(OutputStream out)//指定某个写入流建立一个DataoutputStream类的实例

比较常用的方法是:

public  void  flush()throws  IOException//刷新

public  final  int  size()//返回当前写入此数据输出流的字节数

public  void  write(byte[] b, int off, int len)throws IOException//按照装进数组里数据的有效位数来写入数据

public  void  write(int  b) throws  IOException//将b的低八位写入输出流

public  final  void  writeBoolean(booleanv) throws  IOException//写入一个boolean数据

public  final  void  writeByte(intv) throws  IOException//以字节形式写入数据

public  final  void  writeBytes(String s) throws  IOException//按照字符串字节顺序写入流中

public  final  void  writeChar(intv) throws  IOException//按照char的2个字节形式写入数据

        这一类的方法还有很多,这里就不必多说了,可以总结出一点的是,不同写入格式是按照不同位数写入的。

        基本数据操作的读取流和写入流配合使用的使用要注意,当读取的时候要按写入的顺序读取,不可以混乱。

 
import   java.io.*;
class    Ioliou31
{
        public   static    void  main(String[] args)throws  IOException
         {
         UTFDemo() ;     
         //  method();
         }
        public    static   void  method()   throws IOException
         {
          File  f=new   File("f:\\科学.txt");  //封装目的文件为对象
          FileOutputStream     fos=new    FileOutputStream(f);//关联目的文件的流
          DataOutputStream     dos=new   DataOutputStream(fos);
           //再用专门操作基本类型数据的流的构造函数接收
 
           //以下注意写入的格式
           //不同的写入格式是按照不同位数写入的
          dos.writeInt(56);
          dos.writeBoolean(false);
          dos.writeDouble(15.24);
     /*  */
          FileInputStream    fis=new  FileInputStream(f);
         DataInputStream  dis=new   DataInputStream (fis);     
           //读取的时候注意要按照顺序读取,以及读取的格式
           //不同的读取格式是按照不同的位数来读取的
          int    i   =dis.readInt();
          boolean  bo=dis.readBoolean();
          double   dou=dis.readDouble();
          soc(i+"---"+bo+"---"+dou);
           //特别注意:什么格式写入的就用什么格式读取出来
 
          dos.close();
          dis.close();            
         }
        public   static void  UTFDemo() throws IOException
         {
          File   f=new   File("f:\\科学.txt");  //封装目的文件为对象
 
 
           FileOutputStream     fos=new FileOutputStream(f);//关联目的文件的流
           DataOutputStream     dos=new  DataOutputStream(fos);
 
          dos.writeUTF("这是");//四个字节组成一个字符,一共八个字节
          //writeUTF写入的也是字符串
          FileInputStream    fis=new  FileInputStream(f);
          DataInputStream   dis=new  DataInputStream (fis);
          soc(dis.readUTF());
          //readUTF方法返回的是字符串,用什么格式写就要用什么格式读取
         }
        public  static  void soc(Object  obj)
         {
             System.out.println(obj);          
         }
}

二:操作字节数组流----》

        ByteArrayInputStream和ByteArrayOutputStream两者里面都封装了长度可变的字节数组,目的就是为了操作字节数组的,没有调用到底层资源所以可以不用关闭资源操作。其对应的源设备可以是键盘,硬盘和内存;对应的目的设备是控制台,硬盘和内存。用法上和一般的字节流没有多大区别。

import java.io.*;
class  Ioliou32
{
         public   static  void  main(String[] args) throws IOException
         {
                   ByteArrayInputStream   bais=new  ByteArrayInputStream("哦奥额".getBytes());
                   ByteArrayOutputStream   baos=new ByteArrayOutputStream();
                   int  i=0;
                  while((i=bais.read())!=-1)
                  {
                       baos.write(i);      
                   }
                   File   f=new File("f:\\可乐可乐.java");
                   FileOutputStream    fos=new  FileOutputStream(f);
                   baos.writeTo(fos);    //直接写入字节输出流中   
                 
 
         }
         public  static  void  soc(Object obj)
         {
            System.out.println(obj);       
         }
}

三:转换流和编码表----》

        转换流InputStreamReader和OutputStreamWriter。

编码表有常见的几种:

ASCII美国标准信息交换码,用一个字节的7为表示。

ISO8859-1欧洲码表,拉丁表不识别中文字符,用一个字节表示

GB2312中国编码表

GBK中国升级编码表

Unicode国际标准码,java使用的编码表

UTF-8 最多用3个字节表示一个字符

        对于同一个文件,写入字符的时候与读取字符的时候用的码表需要一致否则容易发生乱码。

        写入的时候是编码,读取的时候就是解码。这也是码表的作用之一。

import   java.io.*;
class  Ioliou33
{
         public  static  void  main(String[] args) throws IOException
         {
            // 分别调用write()和read()做测试;
                  
         }
         public   static void  write() /*写入*/ throws  IOException
         {
                   File   f=new File("f:\\楼宇.txt");
                   FileOutputStream   fos=new FileOutputStream(f);
                   OutputStreamWriter   osw=new OutputStreamWriter(fos,"UTF-8");//要加上编码表版本
                   osw.write("动手打人了");
                   osw.close();
       /*
                   虽然写入之后我们代开f:\\楼宇.java文件看到的依旧是字符,
                   但是本质上文件存储的是编码表上对应的数字,只不过按照指定编码表兑换成字符而已。
                   */   
         }
         public  static  void  read()/*读取*/ throws  IOException
         { 
                   File   f=new File("f:\\楼宇.txt");
                   FileInputStream   fis=new FileInputStream(f);
                   InputStreamReader   isr=new  InputStreamReader(fis,"UTF-8");//编码表版本要对应上
                   /*
                   读取的时候也是按照存储的数字再按照指定的编码表找出对应的字符
                   */
                   char[]    ch=new char[20];
                   int  i=0;
                   while((i=isr.read(ch))!=-1)
                      {
                         soc(new  String(ch,0,i));      
                      }
    
                   isr.close();                     
         }
         public static  void  soc(Object obj)
         {
             System.out.println(obj);   
         }
}
 

如果编码与解码用的不是同一个码表的情况讨论:

 
import   java.util.*;
class  Ioliou34
 
{
         public static    void  main(String[] args)throws  Exception
         {
 
                //分别调用 method()和method2()测试;
         }
         public static    void  method() throws Exception
         {
                   String   s="开始游戏";
                   byte[]  by= s.getBytes("utf-8");//按照utf-8编码表进行编码
                   soc(Arrays.toString(by));
                   String     s2=new String(by,"ISo8859-1");//按照ISo8859-1编码表进行解码
                   soc("s2="+s2);//s2=????§???????
                   //如果按照不同的编码表进行解码的话会导致错误结果
                   //如果遇到这种情况就需要再一次进行编码解码
                   byte[]    by2=s2.getBytes("ISo8859-1");
                   String   s3=new String(by2,"utf-8");
                   soc("s3="+s3);//s3=开始游戏                      
         }
         public static   void method2()  throws Exception
         {
                   String   s="开始游戏";
                   byte[]  by= s.getBytes("utf-8");//按照utf-8编码表进行编码
                   soc(Arrays.toString(by));
                   String   s2=new String(by,"gbk");
                  soc("s2="+s2);//s2=寮?濮嬫父鎴?
 
                   //如果按照不同的编码表进行解码的话会导致错误结果
                   //如果遇到这种情况就需要再一次进行编码解码
                   byte[]    by2= s2.getBytes("gbk");
                   soc(Arrays.toString(by2));
                   String    s3=new String(by2,"utf-8");
                  soc("s3="+s3);//s3=??始游??
                   /*
                   由于gbk和utf-8都是中文编码表,所以,此时的情况与method方法中的不同,
                   method方法中解码过程出错的是因为使用了IOS8895-1拉丁码表,里面不知别中文字符,
                   而这里method2的情况则是解码过程中使用了可以识别中文的gbk码表,
                   解码中遇到对不上号的字符就会去gbk码表的乱码区查找,接着再用gbk码表编码就
                   不是原来的号吗了,所以,这里method2方法的s3就会显示乱码,而method方法的s3则是显示正确。
                  */
         }
         public static   void  soc(Object obj)
         {
             System.out.println(obj);           
         }
}

        还有一个问题是“联通”问题:

        在windows系统中打开一个txt文件,输入“联通”,然后保存关闭再打开,会发现显示的是一个黑块,这是因为编码与解码用的不是同一个表所致的。虽然按照gbk形式写入的,但是“联通”的二进制符合了UTF-8的形式,所以会系统会再打开额时候会去查UTF-8的码表,这就出问题了。


----------- android培训java培训、java学习型技术博客、期待与您交流!------------  

             

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值