JavaI/O流重要方法及代码示例
再复习一下I/O流中类的继承关系
一.字节流
1.输入流:FileInputStream2.输出流:FileOutputStream
示例代码
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestIO {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream fos=null;
FileInputStream fis=null;
//输出字符串到txt文件中
fos=new FileOutputStream("d:/java.txt");
String str="Hello java!\r\n";
//将字符串打散成为一个字节数组
byte[] words=str.getBytes();
fos.write(words,0,words.length);
System.out.println("文件已被更新");
//再输入txt中的字符,在控制台输出
fis=new FileInputStream("d:/java.txt");
byte[] bytes=new byte[1024];
int ch;
System.out.println("文件输出:");
//将文件内容读到缓存byte数组中,ch记录读的字节数,如果文件内容为空则返回-1
while((ch=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,ch));
}
fis.close();
fos.close();
}
}
txt文件及控制台结果
二.字符流
1.输入流:FileReader
①Reader类常用方法:(作用和方法都和FileInputStream一样)
int read()一个一个字符的读,返回数字对应字符的Ascii码
int read(char[] c)将字符读取到char数组中,返回读入的字符数
int read(char[] c,int off,int len)将字符读入到char数组,从哪个位置开始存入,读多长,返回读入的字符数
void close()
②子类InputStreamReader的常用构造方法,一般使用该子类为了解决中文乱码问题
InputStreamReader(InputStream in)
InputStreamReader(InputStream in,String charsetName)参数里可以自己设置输入的字符编码形式
③ 孙子类FileReader类是InputStreamReader的子类【作用和用法都和FileInputStream一样,正常使用就可以】:
FileReader(File file)
FileReader(String name)
该类只能按照系统默认的字符编码来读取数据,不能自己规定编码类型
System.out.println(System.getProperty(“file.encoding”));获得本地平台的字符编码类型
有中文乱码的缺陷所以一般使用InputStreamReader并且和FileInputStream fis = new FileInputStream("……"); 配合着来用
2.输出流FileWriter
①Writer类的常用方法
write(String str)写入字符串
write(String str,int off,int len)
void close()
void flush()
②子类OutputStreamWriter(可以指定字符编码格式)常用的构造方法:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
③孙子类FileWriter:以下两种构造都可以重载,指定一个boolean类型的参数,用来指定追加还是覆盖文件内容
new FileWriter (File file)
new FileWriter (String path)
一定要记住使用.flush()和.close(),这样才能把存在缓冲区中的数据冲出来。
示例代码
public class TestIO {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileWriter fos=null;//读入
FileReader fis=null;//写出
//输出字符串到txt文件中
fos=new FileWriter("d:/java.txt");
String str="Hello java!\r\n";
System.out.println("文件已被更新");
//直接输出字符串
fos.write(str);
fos.close();
//再输入txt中的字符,在控制台输出
System.out.println("文件输出:");
fis=new FileReader("d:/java.txt");
char[] c=new char[1024];
int ch;
//将文件内容读到缓存c数组中,ch记录读的字节数,如果文件内容为空则返回-1
while((ch=fis.read(c))!=-1){
System.out.println(new String(c));
}
fis.close();
}
}
结果和上面一样。
三.缓冲流
1.输入流:BufferedReader2.输出流:BufferedWriter
示例代码
public class TestIO {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedWriter bw=null;
FileWriter fw=null;
Reader reader=null;
BufferedReader br=null;
//输出字符到txt文件中
fw=new FileWriter("d:/java3.txt");
bw=new BufferedWriter(fw);
bw.write("Java3\r\n");
bw.write("输入输出\r\n");
bw.write("举例\r\n");
bw.flush();//清空缓存
bw.close();
System.out.println("文件已被更新");
//再输入txt中的字符,并在控制台输出
reader=new FileReader("d:/java3.txt");
br=new BufferedReader(reader);
//BufferedReader 可以一行一行的读
System.out.println("文件输出");
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
结果 :
四.读写二进制文件
1.输入流:DataInputStream
是FileInputStream的子类
与FileInputStream类结合使用读取二进制文件2.输出流:DataOutputStream
是FileOutputStream的子类
与FileOutputStream类结合使用写二进制文件代码示例
public class TestIO {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//输入流
FileInputStream fis=null;
DataInputStream dis=null;
//输出流
FileOutputStream fos=null;
DataOutputStream dos=null;
fis=new FileInputStream("d:/test/2.jpg");
dis=new DataInputStream(fis);
fos=new FileOutputStream("d:/test/3.jpg");
dos=new DataOutputStream(fos);
int data;
//将图片3复制到图片2
while((data=dis.read())!=-1){
dos.write(data);
}
System.out.println("复制成功");
fis.close();
dis.close();
fos.close();
dos.close();
}
}
结果
序列化和反序列化
1.序列化和反序列化的过程
序列化是将对象的状态写入到特定的流的过程,反序列化是从特定的流中获取数据重新构建对象的过程。
2.对象输入流:反序列化
ObjectInputStream
和FileInputStream结合使用
反序列化的输入方法:.readObject()【Object类型的,需要类型转换】
3. 对象输出流(序列化):
ObjectOutputStream
和FileOutputStream结合使用
序列化的输出方法:.writeObject(Object)
4. 常见异常:
NotSerializableException:类没有实现Serializable接口,不可被序列化;要使用:implements Serializable来实现接口。
如果一个类想被序列化和他所有有关系的类都必须能被系列化(比如它的父类,子类…)
注:
transient(关键字):屏蔽某些敏感字段的序列化
例如:private transient String password
实例代码
1.学生类
import java.io.Serializable;
//学生类,实现Serializable接口
public class Student implements Serializable{
private String name;
private int age;
private String gender;
//transient(关键字):屏蔽某些敏感字段的序列化
private transient String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
//构造方法
public Student(String name, int age, String gender, String password) {
this.name = name;
this.age = age;
this.gender = gender;
this.password = password;
}
}
2.序列化和反序列化
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 SeriaStuDemo {
public static void main(String[] args) throws ClassNotFoundException {
Student stu = new Student("小红",18,"女","123456");
//对象输出流
ObjectOutputStream oos = null;
FileOutputStream fos = null;
//对象输入流
ObjectInputStream ois = null;
FileInputStream fis = null;
try {
//序列化
fos = new FileOutputStream("d:/test/student.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(stu);
//反序列化
fis = new FileInputStream("d:/test/student.txt");
ois = new ObjectInputStream(fis);
Student stu1 = (Student)ois.readObject();
System.out.println("反序列化后的信息:"+stu1.getName()+"-"+stu1.getAge()+"-"+stu1.getGender()+"-"+stu1.getPassword());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
oos.close();
fos.close();
ois.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行展示:
文件夹:
控制台(因为属性password使用了关键字transient,所以被屏蔽不能序列化):