字节流:
输入流:FileInputStream
输出流:FileOutputStream
编程举例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileInputStreamAndOutputStreamDemo {
public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
//输出字符到txt文件中
fos = new FileOutputStream("d:/test/java.txt",true);//加上true表示追加
String str = "Hello java!\r\n";
//将字符打散成为一个字节数组
byte[] words = str.getBytes();
fos.write(words, 0,words.length);
System.out.println("文件已被更新:");
//再输入txt中的字符,并在控制台输出
fis = new FileInputStream("d:/test/java.txt");
// 一个字节一个字节读的方法
// int ch;
// while((ch=fis.read()) != -1){
// System.out.print((char)ch);
// }
byte[] bytes = new byte[1024];
int ch;
//存到数组里读的方法
//ch表示读了多少字节,如果文件内容为空,则为-1
//一次读1024
System.out.println("文件输出:");
while((ch=fis.read(bytes))!=-1){
for(int i = 0;i<ch;i++){
System.out.print((char)bytes[i]);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行展示:
文件夹:
控制台:
字符流:
输入流:FileReader
1. Reader类常用方法
【作用和用法都和InputStream一样,正常使用就可以】:
int read( )
int read(char[ ] c)
read(char[ ] c,int off,int len)
void close( )
为了解决中文乱码使用子类InputStreamReader
2. 子类InputStreamReader常用的构造方法:
InputStreamReader(InputStream in)
InputStreamReader(InputStream in,String charsetName)
【支持输入的字符流,并且可以规定输入的字符编码格式】
3. 孙子类FileReader类是InputStreamReader的子类【作用和用法都和FileInputStream一样,正常使用就可以】:
FileReader(File file)
FileReader(String name)
该类只能按照系统默认的字符编码来读取数据,用户不能指定其他的字符编码类型
System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
有中文乱码的缺陷所以一般使用InputStreamReader并且和FileInputStream fis = new FileInputStream("……"); 配合着来用
输出流:FileWriter
1. Writer类常用方法:
write(String str)
write(String str,int off,int len)
void close()
void flush()
2. 子类OutputStreamWriter(可以指定字符编码格式)常用的构造方法:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
3. 孙子类FileWriter:以下两种构造都可以重载,指定一个boolean类型的参数,用来指定追加还是覆盖文件内容
new FileWriter (File file)
new FileWriter (String path)
一定要记住使用.flush()和.close(),这样才能把存在缓冲区中的数据冲出来。
编程举例:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderAndWriterDemo {
public static void main(String[] args) {
FileWriter fw = null;
FileReader fr = null;
try {
//输出字符到txt文件中
fw = new FileWriter("d:/test/java2.txt",true);//加上true表示追加
//直接写入字符
fw.write("hello java2\r\n");
System.out.println("文件已被更新:");
fw.close();
//再输入txt中的字符,并在控制台输出
fr = new FileReader("d:/test/java2.txt");
// 一个字节一个字节读的方法
// int ch;
// while((ch = fr.read()) !=-1){
// System.out.println((char)ch);
// }
//存到数组里读的方法
//ch表示读了多少字节,如果文件内容为空,则为-1
//一次读1024
System.out.println("文件输出:");
//使用StringBuffer将字符缓存
StringBuffer s=new StringBuffer();
char[] ch =new char[1024];
int len = -1;
while((len = fr.read(ch)) != -1){
s.append(ch); //append方法追加字符
}
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行展示:
文件夹:
控制台:
缓冲流
输入流:BufferedReader
输出流:BufferedWriter
编程举例:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
//借助带缓冲区的字符输出流
//借助字符输入流将文件内容读出来显示在控制台
public class BufferedInputAndOutputDemo {
public static void main(String[] args) {
BufferedWriter bw = null;
FileWriter fw = null;
Reader reader = null;
BufferedReader br = null;
try {
//输出字符到txt文件中
fw=new FileWriter("d:/test/java3.txt",true);
bw = new BufferedWriter(fw);
bw.write("Java3");
bw.newLine();//空行指令
bw.write("输入输出");
bw.newLine();
bw.write("举例");
bw.newLine();
bw.flush();//清空缓存
System.out.println("文件已被更新!");
//再输入txt中的字符,并在控制台输出
reader = new FileReader("d:/test/java3.txt");
br = new BufferedReader(reader);
//BufferedReader可以一行一行的读
System.out.println("文件输出:");
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行展示:
文件夹:
控制台:
读写二进制文件:
输入流:DataInputStream
是FileInputStream的子类
与FileInputStream类结合使用读取二进制文件
输出流:DataOutputStream
是FileOutputStream的子类
与FileOutputStream类结合使用写二进制文件
编程举例:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//用Data流复制图片
public class DataInputAndOutputDemo {
//将d:/test/2.jpg复制到d:/test/3.jpg,并输出复制成功。
public static void main(String[] args) {
//输入流
FileInputStream fis = null;
DataInputStream dis = null;
//输出流
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
fis = new FileInputStream("d:/test/2.jpg");
dis = new DataInputStream(fis);
fos = new FileOutputStream("d:/test/3.jpg");
dos = new DataOutputStream(fos);
int data;
while((data = dis.read()) !=-1){
dos.write(data);
}
System.out.println("复制成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
dos.close();
fos.close();
dis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行展示:
文件夹:
控制台:
序列化、反序列化:
1. 序列化和反序列化的过程:
序列化是将对象的状态写入到特定的流中的过程。
反序列化则是从特定的流中获取数据重新构建对象的过程。
2. 对象输入流(反序列化):
ObjectInputStream
反序列化的输入方法:.readObject()【Object类型的,需要类型转换】
3. 对象输出流(序列化):
ObjectOutputStream
序列化的输出方法:.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,所以被屏蔽不能序列化):