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(); } } }