黑马程序员——IO流(四)

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

1、序列化对象

对象被序列化后,然后存到硬盘的文件中,然后读取的时候可以方便的读取,要被存到硬盘文件中的对象类,必须实现接

Serializable接口,此接口中没有抽象方法,是为了标识类的。

ObjectOutputStream的方法writeObject()和ObjectInputStream的方法readObject(),这两个方法是成对出现的,一个是写,一个是读。

注意:

1.当被序列化的对象存到了硬盘上后,如果原来的类更改了,那么再次读取的时候,会读取失败,因为他们的标识ID被更改了,所以要向更改后,仍可以读取的话,那么在序列化的时候,指定固定的标识ID。static final long serialVersionUID = 42L;

 2.静态成员不能被序列化,因为序列化的都是在堆中,而静态的成员实在方法区中,如果非静态成员要向也不被序列化,那么由关键字:transient修饰,那么就会不被序列化。

3.当文件中存储了多个对象,那么读取的时候没调用一次readObject方法,就读取一个对象。

2、例子

用序列标识号来标识类,那么原来的类更改了一些操作,那么也可以继续使用硬盘中被序列化的文件对象。

import java.io.Serializable;

public class Person implements Serializable {

   static final long serialVersionUID = 42L;

   private String name;

   int age;

   public Person(String name, int age) {

     this.name = name;

     this.age = age;

   }

 

   public String toString() {

     return name + ":" + age;

   }

}

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

 

public class SerDemo {

   public static void main(String[] args) throws Exception {

 

     // WritePerson();

     ReadPerson();

   }

   /* 写 */

   private static void ReadPerson() throws IOException,FileNotFoundException,

        ClassNotFoundException {

     ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

          "F:\\per.txt"));

     Person p = (Person) ois.readObject();

     System.out.println(p);

   }

 

   /* 读 */

   private static void WritePerson() throws IOException,FileNotFoundException {

     ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

          "F:\\per.txt"));

     oos.writeObject(new Person("zhangsan", 23));

     oos.close();

   }

 

}

结果:

zhangsan:23

3、管道流

     将输入流和输出流。连接起来有两种方式:利用构造函数,或者用connect()方法。

public class Write implements Runnable {

   private PipedOutputStream out = null;

 

   public Write(PipedOutputStream out) {

     super();

     this.out = out;

   }

 

   public void run() {

 

     try {

        System.out.println("开始写入数据,等待");

        Thread.sleep(4000);

        out.write("guandao".getBytes());

        out.close();

     } catch (IOException e) {

        e.printStackTrace();

     } catch (InterruptedException e) {

        e.printStackTrace();

      }

   }

 

}

import java.io.IOException;

import java.io.PipedInputStream;

public class Read implements Runnable {

   private PipedInputStream in = null;

 

   public Read(PipedInputStream in) {

     this.in = in;

   }

 

   public void run() {

 

     try {

        System.out.println("没有数据可读");

        byte [] b=new byte[1024];

        int len=in.read(b);

        System.out.println("读到数据");

        System.out.println(new String(b,0,len));

     } catch (IOException e) {

        e.printStackTrace();

     }

   }

}

 

import java.io.IOException;

import java.io.PipedInputStream;

import java.io.PipedOutputStream;

public class PideDemo {

   public static void main(String[] args)throws IOException {

     PipedOutputStream pds=new PipedOutputStream();

     PipedInputStream pis=new PipedInputStream();

     pds.connect(pis);//链接

        Write w=new Write(pds);

        Read r=new Read(pis);

        new Thread(w).start();

        new Thread(r).start();

   }

 

}

结果:

开始写入数据,等待

没有数据可读

读到数据

Guandao

4、RandomAccessFile

随机访问文件,自身具备读写方法

1.特点:

不是IO包中的子类,直接继承Object但是是IO包成员,既可以读也可以写。内部封装一个数组,通过指针进行操作。

可以通过getFilePointer()和seek()方法设置指针的位置

2. 读写原理:就是内部分装了字节输入流和输出流。

3.通过构造函数知,只能操作文件。有模式:r,rw,rws,rwdbv

4. 跳过指定的字节数skipBytes(n);只能向后跳

5.如果模式是r,不会创建文件,会去读一个已经存在的文件,不存在,则抛出异常。如果模式是rw,操作文件不存在,则自动创建,要是文件存在,则不会覆盖。

import java.io.File;

import java.io.IOException;

import java.io.RandomAccessFile;

 

public class RandomAccessFileDemo {

   public static void main(String[] args) throws IOException {

     RandomAccessFile raf = new RandomAccessFile(new File("F:\\demo.txt"),

          "rw");// 可读可写

     /*写*/

     raf.write("张三".getBytes());

     raf.write(23);

 

     raf.close();

     raf = new RandomAccessFile(new File("F:\\demo.txt"), "rw");// 可读可写

     /*读*/

     byte[] b = new byte[4];

     int l = raf.read(b);

     System.out.println(new String(b, 0, l));

   }

 

}

 5、 DataInputStream和DataOutputStream

    用来操作基本数据类型的类。

注意:writeUTF方法是用来操作指定写入的编码是utf-8方式,但是他是修改版本,在此写入的文件,只能应此对象来读取,其他的对象是读取不出来的,因为是修改版的。

public static void main(String[] args) throws IOException {

    

     DataWrite();

     DataRead();

   }

   public static void DataWrite() throws IOException{

     DataOutputStream out=new DataOutputStream(new FileOutputStream("F:\\data.txt"));

       out.writeInt(123);

       out.writeBoolean(true);

       out.writeDouble(34.87);

       out.writeDouble(1.1);

       out.close();

   }

   public static void DataRead() throws IOException{

      DataInputStream in=new DataInputStream(new FileInputStream("F:\\data.txt"));

       int a=in.readInt();

       boolean b=in.readBoolean() ;

       double c=in.readDouble();

       in.close();

       System.out.println(a);

       System.out.println(b);

       System.out.println(c);

   }

结果:

123

true

34.87

 6、ByteArrayInputStreamByteArrayOutputStream

用于操作字节数组

这两个流对象操作的数组,没有使用系统资源(没有创建文件),所以不用关闭。

ByteArrayInputStream:不用定义数据目的,因为封装了一个可变的字节数组

在流操作的规律中:

源和目的除了:键盘和文件,还有内存,内存就是ByteArrayInputStream和ByteArrayOutputStream,就是操作字节数组流。

public static void main(String[] args) throws IOException {

     ByteArrayInputStream in=new ByteArrayInputStream("abcd".getBytes());

     ByteArrayOutputStream out=new ByteArrayOutputStream();

     int ch=0;

     while((ch=in.read())!=-1){

        out.write(ch);

     }

     System.out.println(out.size());

     System.out.println(out.toString());

   }

7、编码表

ISO8859-1:属于单字节编码方式,主要是在0~255字符范围,只要在英语在英文上。

GBK/GBK2312:中文的编码方式,只要是标识汉字,

Unicod:使用的是16进制的编码方式。

UTF:可以是字符的长度是1-6字符,这样可以节约空间。兼容所有字符。

 

   转换流之间的编码

   编码表:就是把各个国家的文字全部用数字表示出来,应用于计算机,那么这样就形成了一个表,就是编码表

GBK:一个汉字站两个字节

UTF-8:一个汉字占三个字节

同样的编码方式要用同样的变法方式读取,否则会出现乱码

public class Text {

  public static void main(String[] args) throws IOException {

    //writeTxt();

    readTxt();

  }

 

  public static void writeTxt() throws IOException{

    OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("F:\\utf.txt"),"utf-8");

       writer.write("大家好");

       writer.close();

  }

  public static void readTxt() throws IOException{

    InputStreamReader reader=new InputStreamReader(new FileInputStream("F:\\utf.txt"),"utf-8");

       char []bu=new char[20];

       int len=reader.read(bu);

       System.out.println(new String(bu,0,len));

       reader.close();

  }

}

 8、字符的编码和解码

编码:字符串变成字节数组String—>byte[]String.getBytes(charsetName);

解码:字节数组变成字符串byte[]->String    new String(byte[],chatsename)

public class Text {

  public static void main(String[] args) throwsUnsupportedEncodingException  {

    String s1="你好";

    byte [] b1=s1.getBytes("GBK");

    System.out.println(Arrays.toString(b1));//编码表

   

    //假如编码方式变了

    String s2=new String(b1,"ISO8859-1");

    System.out.println(s2);

    byte [] b2=s2.getBytes("ISO8859-1");

    System.out.println(Arrays.toString(b2));//编码表

   

    System.out.println(new String(b1,"GBK"));

  }

}

结果:

[-60, -29, -70, -61]

????

[-60, -29, -70, -61]

你好

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值