JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码

一、对象序列化

1.1、对象序列化

被操作的对象需要实现Serializable接口

1.2、对象序列化流ObjectOutputStream与ObjectInputStream

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。

抛出:InvalidClassException - 序列化操作使用的类出了问题。NotSerializableException - 某个要序列化的对象不能实现 java.io.Serializable 接口。IOException - 由底层 OutputStream 抛出的任何异常。

示例一、对象序列化

package com.pb.io.demo7;

import java.io.Serializable;

/**
 * 用户类
 *
 */
public class User implements Serializable{

    /**
     * 序列号
     */
    private static final long serialVersionUID = 1031444657618620970L;
    private String name;
    private String password;
    private int age;
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    public User(String name, String password, int age) {
        super();
        this.name = name;
        this.password = password;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("姓名:"+this.name+",年龄:"+this.age+",密码:"+this.password);
    }

}
package com.pb.io.demo7;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStreamDemo {

    public static void main(String[] args) {

        File file = new File("d:\\user.txt");
        writeObj(file);
        readObj(file);
    }

    // 序列化
    public static void writeObj(File file) {
        System.out.println("=====开始序列化=====");
            //声明序列化流
        ObjectOutputStream oos=null;
        try {
             oos=new ObjectOutputStream(new FileOutputStream(file));
             //声明对象,并初始化
             User u=new User("张三","123qwe",23);
             //序列化,写入文件
             oos.writeObject(u);
             System.out.println("=====序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{

                try {
                    if(oos!=null){
                    oos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    // 反序列化
    public static void readObj(File file) {
        System.out.println("=====开始反序列化=====");
        //声明反序列化流
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(file));
            //反序列化,读出的Object,要强制类型转换
            User u=(User)ois.readObject();
            //显示属性
            u.show();
            System.out.println("=====反序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

=====开始序列化=====
=====序列化完成=====
=====开始反序列化=====
姓名:张三,年龄:23,密码:123qwe
=====反序列化完成=====

示例二、静态成员不能被序列化

package com.pb.io.demo7;

import java.io.Serializable;

/**
 * 用户类
 *
 */
public class User implements Serializable{

    /**
     * 序列号
     */
    private static final long serialVersionUID = 1031444657618620970L;
    private String name;
    private  String password;
    private int age;
    private static String country="cn";
    public User() {
        super();
    }
    public User(String name, String password, int age,String country) {
        super();
        this.name = name;
        this.password = password;
        this.age = age;
        this.country=country;

    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("姓名:"+this.name+",年龄:"+this.age+",密码:"+this.password+",国家:"+country);
    }

}
package com.pb.io.demo7;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStreamDemo {

    public static void main(String[] args) {

        File file = new File("d:\\user.txt");
        writeObj(file);
        //分开执行不能同时执行
        readObj(file);
    }

    // 序列化
    public static void writeObj(File file) {
        System.out.println("=====开始序列化=====");
            //声明序列化流
        ObjectOutputStream oos=null;
        try {
             oos=new ObjectOutputStream(new FileOutputStream(file));
             //声明对象,并初始化
             User u=new User("张三","123qwe",23,"天朝");
             //序列化,写入文件
             oos.writeObject(u);
             System.out.println("=====序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{

                try {
                    if(oos!=null){
                    oos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    // 反序列化
    public static void readObj(File file) {
        System.out.println("=====开始反序列化=====");
        //声明反序列化流
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(file));
            //反序列化,读出的Object,要强制类型转换
            User u=(User)ois.readObject();
            //显示属性
            u.show();
            System.out.println("=====反序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

=====开始反序列化=====
姓名:张三,年龄:23,密码:123qwe,国家:cn
=====反序列化完成=====

示例三、transient修饰的成员不会被序列化

package com.pb.io.demo7;

import java.io.Serializable;

/**
 * 用户类
 *
 */
public class User implements Serializable{

    /**
     * 序列号
     */
    private static final long serialVersionUID = 1031444657618620970L;
    private String name;
    private transient  String password; //加上transient关键字,保护不会被序列化
    private int age;

    public User() {
        super();
    }
    public User(String name, String password, int age) {
        super();
        this.name = name;
        this.password = password;
        this.age = age;

    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("姓名:"+this.name+",年龄:"+this.age+",密码:"+this.password);
    }

}
package com.pb.io.demo7;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStreamDemo {

    public static void main(String[] args) {

        File file = new File("d:\\user.txt");
        writeObj(file);
        //分开执行不能同时执行
        readObj(file);
    }

    // 序列化
    public static void writeObj(File file) {
        System.out.println("=====开始序列化=====");
            //声明序列化流
        ObjectOutputStream oos=null;
        try {
             oos=new ObjectOutputStream(new FileOutputStream(file));
             //声明对象,并初始化
             User u=new User("张三","123qwe",23);
             //序列化,写入文件
             oos.writeObject(u);
             System.out.println("=====序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{

                try {
                    if(oos!=null){
                    oos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    // 反序列化
    public static void readObj(File file) {
        System.out.println("=====开始反序列化=====");
        //声明反序列化流
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(file));
            //反序列化,读出的Object,要强制类型转换
            User u=(User)ois.readObject();
            //显示属性
            u.show();
            System.out.println("=====反序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

=====开始序列化=====
=====序列化完成=====
=====开始反序列化=====
姓名:张三,年龄:23,密码:null
=====反序列化完成=====

示例四、序列多个对象或者集合

Person引用以上示例三

package com.pb.io.demo7;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class ObjectStreamDemo {

    public static void main(String[] args) {

        File file = new File("d:\\user.txt");
        writeObj(file);
        //分开执行不能同时执行
        readObj(file);
    }

    // 序列化
    public static void writeObj(File file) {
        System.out.println("=====开始序列化=====");
            //声明序列化流
        ObjectOutputStream oos=null;
        try {
             oos=new ObjectOutputStream(new FileOutputStream(file));
             //声明对象,并初始化
             User u1=new User("张三","123qwe",23);
             User u2=new User("李四","456tyu",21);
             User u3=new User("王五","asdf",23);
             User u4=new User("赵六","bnme",23);
             ArrayList<User> users=new ArrayList<User>();
             users.add(u1);
             users.add(u2);
             users.add(u3);
             users.add(u4);
             //序列化,写入文件
             oos.writeObject(users);
             System.out.println("=====序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{

                try {
                    if(oos!=null){
                    oos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    // 反序列化
    public static void readObj(File file) {
        System.out.println("=====开始反序列化=====");
        //声明反序列化流
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(file));
            //反序列化,读出的Object,要强制类型转换
            ArrayList<User> users=(ArrayList<User>)ois.readObject();
            //显示属性
            for(User u:users){
                u.show();
            }
            System.out.println("=====反序列化完成=====");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

=====开始序列化=====
=====序列化完成=====
=====开始反序列化=====
姓名:张三,年龄:23,密码:null
姓名:李四,年龄:21,密码:null
姓名:王五,年龄:23,密码:null
姓名:赵六,年龄:23,密码:null
=====反序列化完成=====

示例王、引用类型的对象序列化

package com.pb.io.demo7;

import java.io.Serializable;

/**
 * 学生
 *
 */
public class Student implements Serializable {

    private String name;
    private int age;
    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public void show(){
        System.out.println("学生姓名:"+this.name+",年龄:"+this.age);
    }
}
//=================
package com.pb.io.demo7;

import java.io.Serializable;

/**
 * 教师类
 *
 */
public class Teacher implements Serializable{

    /**
     *
     */
    private static final long serialVersionUID = 8053946921233636502L;
    private String name;
    private Student stu; //引用学生引做为属性

    public Teacher() {
        super();
    }

    public Teacher(String name, Student stu) {
        super();
        this.name = name;
        this.stu = stu;
    }

    public void show(){
        System.out.println("教师姓名:"+this.name);
        stu.show();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Student getStu() {
        return stu;
    }

    public void setStu(Student stu) {
        this.stu = stu;
    }

}
package com.pb.io.demo7;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStreamDemo1 {

    public static void main(String[] args) {
        File file=new File("d:\\teacher.txt");

        writeObj(file);
        //分开执行不能同时执行
        readObj(file);

    }
    //序列化
    public static void writeObj(File file){
        ObjectOutputStream oos=null;
        try {
            oos=new ObjectOutputStream(new FileOutputStream(file));
            Student stu=new Student("张三",21);
            //声明教师对象,并引用同一个学生
            Teacher t1=new Teacher("李老师",stu);
            Teacher t2=new Teacher("王老师",stu);
            //序列化
            oos.writeObject(t1);
            oos.writeObject(t2);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(oos!=null)
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void readObj(File file){
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(file));
            //反序列化
            Teacher t1=(Teacher)ois.readObject();
            Teacher t2=(Teacher)ois.readObject();
            //显示
            t1.show();
            t2.show();
            //判断2个老师的学生是不是同一个学生
            if(t1.getStu()==t2.getStu()){
                System.out.println("李老师和王老师教的是同一个学生");
            }else{
                System.out.println("李老师和王老师教的不是同一个学生");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

教师姓名:李老师
学生姓名:张三,年龄:21
教师姓名:王老师
学生姓名:张三,年龄:21
李老师和王老师教的是同一个学生

二、管道流

2.1、PipedInputStream与PipedOutputStream

管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏

可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。通常,数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取。不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。如果某个线程正从连接的管道输入流中读取数据字节,但该线程不再处于活动状态,则该管道被视为处于 毁坏 状态

输入输出可以直接进行连接,通过结合多线程使用

字段摘要
protected byte[] buffer
放置传入数据的循环缓冲区。
protected
int
in

循环缓冲区中位置的索引,当从连接的管道输出流中接收到下一个数据字节时,会将其存储到该位置。

protected
int
out

循环缓冲区中位置的索引,此管道输入流将从该位置读取下一个数据字节。

protected
static int
PIPE_SIZE

管道循环输入缓冲区的默认大小。


构造方法摘要
PipedInputStream()

创建尚未连接
PipedInputStream

PipedInputStream(int pipeSize)

创建一个尚未连接
PipedInputStream,并对管道缓冲区使用指定的管道大小。

PipedInputStream(PipedOutputStream src)

创建 PipedInputStream,使其连接到管道输出流
src

PipedInputStream(PipedOutputStream src,
int pipeSize)

创建一个 PipedInputStream,使其连接到管道输出流
src,并对管道缓冲区使用指定的管道大小。


方法摘要
int available()

返回可以不受阻塞地从此输入流中读取的字节数。

void close()

关闭此管道输入流并释放与该流相关的所有系统资源。

void connect(PipedOutputStream src)

使此管道输入流连接到管道输出流 src

int read()

读取此管道输入流中的下一个数据字节。

int read(byte[] b,
int off, int len)

将最多 len 个数据字节从此管道输入流读入 byte
数组。
protected
void
receive(int b)

接收数据字节。


构造方法摘要
PipedOutputStream()
创建尚未连接到管道输入流的管道输出流。
PipedOutputStream(PipedInputStream snk)

创建连接到指定管道输入流的管道输出流。


方法摘要
void close()

关闭此管道输出流并释放与此流有关的所有系统资源。

void connect(PipedInputStream snk)

将此管道输出流连接到接收者。

void flush()

刷新此输出流并强制写出所有缓冲的输出字节。

void write(byte[] b,
int off, int len)

len 字节从初始偏移量为
off 的指定 byte 数组写入该管道输出流。
void write(int b)

将指定 byte 写入传送的输出流。


从类 java.io.OutputStream 继承的方法
write


2.2、示例

package com.pb.io.demo8;

import java.io.IOException;
import java.io.PipedInputStream;

public class Read implements Runnable {
    private PipedInputStream pis;
    public Read(PipedInputStream pis){
        this.pis=pis;
    }

    @Override
    public void run() {
        byte []     buf=new byte[1024];
        int len=0;

            try {
                while((len=pis.read(buf))!=-1){
                    String str=new String(buf,0,len);
                    System.out.println(str);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(pis!=null)
                    pis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

    }

}
//================
package com.pb.io.demo8;

import java.io.IOException;
import java.io.PipedOutputStream;
import java.util.Scanner;

public class Write implements Runnable{
    private PipedOutputStream pos;
    Scanner input=new Scanner(System.in);
    public Write(PipedOutputStream pos){
        this.pos=pos;
    }
    @Override
    public void run() {
        try {
            System.out.println("开始写入");
        while(true){
            String str=input.nextLine();
            if(str.equals("over"))
                break;
            pos.write(str.getBytes());

        }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                pos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
package com.pb.io.demo8;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class Demo {

    public static void main(String[] args) throws IOException {
        PipedInputStream pis=new PipedInputStream();
        PipedOutputStream pos=new PipedOutputStream();
        pis.connect(pos);

        Thread t1=new Thread(new Read(pis));
        Thread t2=new Thread(new Write(pos));
        t1.start();
        t2.start();
    }

}

三、RandomAccessFile

3.1、概述

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

通过skipBytes(int x),seek(int x)来达到随机访问

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

mode 参数指定用以打开文件的访问模式。允许的值及其含意为:



含意

"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。 

3.2、示例

package com.pb.io.demo8;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessDemo {

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

        File file =new File("d:\\kk.txt");
        //write(file);
        read(file);
    }
    //写入
    public static void write(File file) throws IOException{
        //声明对象,模式为读写
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        raf.write("张三".getBytes());
        System.out.println("张三".getBytes().length);//6个字节
        raf.writeInt(32);//4个字节

        //设置指针
        raf.seek(4*10);
        raf.write("李四".getBytes());
        raf.writeInt(32);
        //修改第一个
        raf.seek(0);
        raf.write("赵六".getBytes());
        raf.writeInt(45);
        raf.close();
    }
    //读取入
        public static void read(File file) throws IOException{
            //声明对象,模式为读
            RandomAccessFile raf=new RandomAccessFile(file,"r");
            byte [] buf=new byte[6];
            raf.read(buf);
            String name=new String(buf);
            int age=raf.readInt();
            System.out.println(name);
            System.out.println(age);
            //读取指定位置的数据
            raf.seek(40);
            raf.read(buf);
            String name1=new String(buf);
            int age1=raf.readInt();
            System.out.println(name1);
            System.out.println(age1);
            raf.close();
        }
}

四、操作基本数据类型的流对象DataStream

4.1、二进制流

数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入

数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。

DataInputStream 对于多线程访问不一定是安全的。 线程安全是可选的,它由此类方法的使用者负责。

4.2、示例

/*
DataInputStream与DataOutputStream
*/
import java.io.*;
class DateStreamDemo
{
    public static void main(String[] args) throws IOException
    {
        File file =new File("d:\\data.txt");
        readData(file);
    }

    /*
    写入基本类行数据
    */
    public static void writeData(File file) throws IOException
    {
        DataOutputStream dos=new DataOutputStream(new FileOutputStream(file));
        dos.writeInt(343);
        dos.writeBoolean(true);
        dos.writeDouble(3.14);
        dos.writeUTF("您好!");
        dos.close();
    }
    /*
    读取基本数据类型数据
    */
    public static void readData(File file) throws IOException
    {
        DataInputStream dis=new DataInputStream(new FileInputStream(file));
        int num=dis.readInt();
        boolean flag=dis.readBoolean();
        double d=dis.readDouble();
        String str=dis.readUTF();
        System.out.println("num="+num);
        System.out.println("flag="+flag);
        System.out.println("d="+d);
        System.out.println("str="+str);
    }
}

五、ByteArrayStream

5.1、概述

此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray()toString() 获取数据。

关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

构造方法摘要
ByteArrayOutputStream()
创建一个新的 byte 数组输出流。
ByteArrayOutputStream(int size)

创建一个新的 byte
数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。

ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

构造方法摘要
ByteArrayInputStream(byte[] buf)
创建一个 ByteArrayInputStream,使用 buf
作为其缓冲区数组。
ByteArrayInputStream(byte[] buf,
int offset, int length)

创建
ByteArrayInputStream,使用 buf
作为其缓冲区数组。

5.2、示例

/*
ByteArrayInputStream:
ByteArrayOutputStream:
*/
import java.io.*;
class ByteStreamDemo
{
    public static void main(String[] args)
    {
        ByteArrayInputStream bais=new ByteArrayInputStream("你好,世界".getBytes());
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        int len=0;
        while((len=bais.read())!=-1)
        {
            bos.write(len);
        }
        System.out.println(bos.size());
        System.out.println(bos.toString());
    }

}
/*
ByteArrayInputStream:
ByteArrayOutputStream:
*/
import java.io.*;
class ByteStreamDemo
{
    public static void main(String[] args) throws IOException
    {
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("d:\\3.txt"));
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        FileOutputStream fos=new FileOutputStream("d:\\y.txt");
        int len=0;
        while((len=bis.read())!=-1)
        {
            bos.write(len);
        }
        System.out.println(bos.size());
        System.out.println(bos.toString());
        //将内存中的数据写到输出流中
        bos.writeTo(fos);
        fos.close();
        bis.close();
    }

}

六、转换流的字符编码

6.1、InputStreamReader与OutputStreamReader

这2个对象在构造方法时候可以加入字符集

6.2、示例

import java.io.*;
class EncodeDemo
{
    public static void main(String[] args) throws IOException
    {
        File gbk=new File("d:\\gbk.txt");
        File utf=new File("d:\\utf.txt");
        //writeGBK(gbk);
        //writeUTF(utf);
        //readGBK(gbk);
        readUTF(utf);
    }
    /*
    GBK编码写入
    */
    public static void writeGBK(File gbk) throws IOException
    {
        OutputStreamWriter osw=new OutputStreamWriter((new FileOutputStream(gbk)),"gbk");
        osw.write("您好");
        osw.close();
    }
/*
    GBK编码读取
    */
    public static void readGBK(File gbk) throws IOException
    {
        InputStreamReader isr=new InputStreamReader((new FileInputStream(gbk)),"gbk");
        char[] ch=new char[10];
        int len=isr.read(ch);
        String str=new String(ch,0,len);
        System.out.println(str);
        isr.close();
    }

    /*
    UTF-8编码写入
    */
    public static void writeUTF(File utf) throws IOException
    {
        OutputStreamWriter osw=new OutputStreamWriter((new FileOutputStream(utf)),"utf-8");
        osw.write("您好");
        osw.close();
    }
    /*
    UTF-8编码读取
    */
    public static void readUTF(File utf) throws IOException
    {
        InputStreamReader isr=new InputStreamReader((new FileInputStream(utf)),"utf-8");
        char [] buf=new char[1024];
        int len=isr.read(buf);
        String str=new String(buf,0,len);
        System.out.println(str);
        isr.close();
    }
}

6.3、示例二

/*
编码:String-->byte[]  str.getBytes(charsetName);

解码: byte[] --->String  new String(byte[],charsetName)
*/
import java.util.*;
class EncodeDemo1
{
    public static void main(String[] args) throws Exception
    {
        String s="您好!";
        //解码
        byte[] buf=s.getBytes("utf-8");
        System.out.println(Arrays.toString(buf));
        //解码
        String s1=new String(buf,"utf-8");
        System.out.println(s1);
    }
}

6.4、示例三

/*
编码:String-->byte[]  str.getBytes(charsetName);

解码: byte[] --->String  new String(byte[],charsetName)
*/
import java.util.*;
class EncodeDemo1
{
    public static void main(String[] args) throws Exception
    {
        String s="您好!";
        //解码
        byte[] buf=s.getBytes("utf-8");
        System.out.println(Arrays.toString(buf));
        //解码 解错
        String s1=new String(buf,"iso8859-1");
        System.out.println(s1);
        //再次解码
        String s2=new String(s1.getBytes("iso8859-1"),"utf-8");
        System.out.println(s2);
    }
}

6.5、示例四

package com.pb.io.demo9;

public class Student implements Comparable<Student>{

    private String name;
    private int ma,cn,en;
    private int sum;
    public Student(String name, int ma, int cn, int en) {
        super();
        this.name = name;
        this.ma = ma;
        this.cn = cn;
        this.en = en;
        this.sum = ma+cn+en;
    }
    public Student() {

    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getMa() {
        return ma;
    }
    public void setMa(int ma) {
        this.ma = ma;
    }
    public int getCn() {
        return cn;
    }
    public void setCn(int cn) {
        this.cn = cn;
    }
    public int getEn() {
        return en;
    }
    public void setEn(int en) {
        this.en = en;
    }
    public int getSum() {
        return sum;
    }
    public void setSum(int sum) {
        this.sum = sum;
    }
    /*
    比较器方法
     */
    @Override
    public int compareTo(Student stu) {
        int num=new Integer(this.sum).compareTo(new Integer(stu.sum));
        if(num==0){
            return this.name.compareTo(stu.name);
        }
        return num;
    }

    @Override
    public int hashCode(){
        return name.hashCode()+sum*78;
    }
    @Override
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("类型不匹配");

        Student s=(Student)obj;
        return this.name.equals(s.name)&& this.sum==s.sum;

    }

    public String toString(){
        return "student["+name+","+ma+","+cn+","+en;
    }
}
package com.pb.io.demo9;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class StudentTools {
    //获取学生信息
    public static Set<Student> getStudents() throws IOException {
        return getStudents(null);
    }
    //获取学生信息
    public static Set<Student> getStudents(Comparator<Student> cmp) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //声明集合
        Set<Student> stus=null;
        //判断比较器是否为空
                if(cmp==null){
                    stus=new TreeSet<Student>();
                }else{
                    stus=new TreeSet<Student>(cmp);
                }
        // 开始读取
        String line = null;
        System.out.println("请输入学生姓名,数学,中文,英文成绩,中间以,分隔");
        while ((line = br.readLine()) != null) {
            if ("over".equals(line)) {
                break;
            }
            String[] info = line.split(",");
            Student stu = new Student(info[0], Integer.parseInt(info[1]), Integer.parseInt(info[2]),
                    Integer.parseInt(info[3]));
            //添加集合
            stus.add(stu);
        }
        br.close();
        return stus;
    }
    //写入文件
    public static void writeFile(Set<Student> stus) throws IOException{
        BufferedWriter bufw=new BufferedWriter(new FileWriter("d:\\stus.txt"));
        //遍历写入文件
        for(Student s:stus){
            bufw.write(s.toString()+"\t");
            bufw.write(s.getSum()+"");
            bufw.newLine();
            bufw.flush();
        }
        bufw.close();
    }
}
package com.pb.io.demo9;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;

/**
 * 5个学生,每个学生有3门课成绩
 * 从键盘输入以上数据(姓名,三门课成绩
 * 输入的格式,如Zhangsan,30,40,60计算出总成绩
 * 并把学生的信息和计算出的总分数高低顺序放在磁盘文件stud.txt
 *
 *
 */
public class Test {

    public static void main(String[] args) {
        StudentTools st=new StudentTools();
        //强行反转比较器
        Comparator<Student> cmp=Collections.reverseOrder();
        //获取学生信息
        try {
            Set<Student> stus=st.getStudents(cmp);
            st.writeFile(stus);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
时间: 2024-08-26 06:10:32

JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码的相关文章

JAVA基础学习之路(四)定义简单java类

简单java类开发一般原则: 类名称必须有意义,再怎么说,要让人家看的明白吧 类之中所有属性必须使用private封装,并提供setter,getter方法 类之中可以有多个构造方法,但是必须保留有一个无参数构造方法 类之中不允许出现任何输出语句,所有输出必须交给被调用处 类之中需要有一个可以取得对象完整信息的方法,一般叫做getInfo(),返回String型数据 class Book { private String name; private int price; private int

Java基础学习笔记二十四 MySQL安装图解

.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”. 2.选择安装类型,有“Typical(默认)”.“Complete(完全)”.“Custom(用户自定义)”三个选项,选择“Custom”,按“next”键继续. 3.点选“Browse”,手动指定安装目录. 4.填上安装目录,我的是“F:\Server\MySQL\MySQL Server 5.0”,也建议不要放在与操作系统同一分区,这样可以防止系统备份还

Java基础学习总结——Java对象的序列化和反序列化

一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些s

java基础学习总结——流

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——流 一.JAVA流式输入/输出原理 流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象,真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据,我们想读文件里面的数据怎么办呢?是通过一个流的方式来读,咱们要想从程序读数据,对于计算机来说,无论读什么类型的数据都是以010101101010这样的形式读取的.怎么把文件里面的数据读出来呢?你可以把文件想象成一

java基础学习总结——网络编程

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——网络编程 一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程. 二.网络通信协议及接口 三.通信协议分层思想 四.参考模型 五.IP协议 每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了. IP地址是用一个点来分成四段的,在计算机内部IP地址是用四个字节来表示的,一个字节代表一段,每一个字节代表的数最大只能到达255. 六.TCP协议和UD

JAVA基础学习流程

JAVA基础学习: 第一步:学习JAVA的开发环境配置.开发第一个Java程序.也建议大家开始使用eclipse等IDE,不必纠结是不是一定要从记事本开始. 第二步:学习数据类型.运算符.变量.这是编程的基础,是程序的“砖块”.这些内容大多数编程语言都有,而且非常类似. 第三步:学习控制语句.这是编程的基础,是程序的“混凝土”.有了控制语句+变量,理论上你就可以写任意的程序了.因此,这是进入程序的门槛,需要大量的练习. 第四步:学习面向对象基础.通过类.对象.包等基本概念讲解.学习的时候,一定要

Java基础学习总结--多态

一.面向对象的三大特性:封装.继承.多态 ? 从一定角度来看,封装和继承几乎都是为多态而准备的. 二.什么是多态? ? 指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用) 三.实现多态的技术以及三个必要条件: ? 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法. 三个必要条件: 继承 重写 父类引用指向子类对象 四.多态的作用.好处.类型

Thinking in java 琐碎知识点之 I/O流 、对象序列化

Java I/O流 .对象序列化 1.File类 此类的实例可能表示(也可能不表示)实际文件系统对象,如文件或目录. File类可以新建.删除和重命名文件和目录,但是File不能访问文件本身的内容,这要使用IO流. File对象的createNewFile()方法在磁盘上创建真实的文件 例程:FileTest.java import java.io.*; public class FileTest { public static void main(String[] args) throws I

No_16_0324 Java基础学习第二十三天

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.03.24 lutianfei none 登录注册IO版 如下代码仅为UserDaoImpl类文件,其他原码参考day22_login_regist工程 public class UserDaoImpl implements UserDao { // 为了保证文件一加载就创建 private static File file = new File("user.txt"); static { try { fil