字符流
按照读取数据单元分,java的流可分为字节流和字符流。
其中字节流为InputStream和OutPutStream,字符流为Reader和Writer。在前面我们已经介绍了字节流,本次我们介绍字符流:
Reader类
FileReader类
FileReader的直接父类是InputStreamReader
其构造方法有两种:
FileReader(File file)
FileReader(String name)
示例:
// FileReader读取文件
public static String readFile(String path){
// 此处的File对象可以省略,然后将path方法FileReader的带参构造中
File f = new File(path);
FileReader fr = null;
String str = null;
try {
fr = new FileReader(f);
char[] c = new char[(int)f.length()];
fr.read(c);
str = new String(c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return str;
}
InputStreamReader类
常常我们读取的文件中会带有中文,但是又不方便改变文件的编码方式,就很容易造成乱码的现象,故这个时候就可以InputStreamReader类,该类提供了一个带参构造,可以指定读取文件的编码方式
public static String readerBuffer(String path){
// InputStreamReader带参构造中需要一个InputStream作为参数,故在此定义一个
FileInputStream fis = null;
InputStreamReader isr = null;
String str = null;
try {
fis = new FileInputStream(path);
isr = new InputStreamReader(fis);
char[] c = new char[(int)f.length()];
isr.read(c);
str = new String(c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return str;
}
Writer类
FileWriter类
FileWriter的直接父类是OutputStreamWriter类
public static void writerFile(String str,String path,boolean isAppend){
File f = new File(path);
FileWriter fw = null;
try {
fw = new FileWriter(f,isAppend);
fw.write(str);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutputStreamWriter类
public static void writerFile(String str,String path,boolean isAppend){
FileOutputStream fos = null;
OutputStreamWriter osw = null;
try {
fos = new FileOutputStream(path);
osw = new OutputStreamWriter(fos);
osw.write(str);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader和BufferedWriter类
为了提高字符读取、写入的速率,我们可以使用BufferedReader和BufferedWriter类
// 文件读取
public static String readerBuffer(String path){
File f = new File(path);
FileReader fr = null;
BufferedReader br = null;
String str = null;
try {
fr = new FileReader(f);
br = new BufferedReader(fr);
String s = null;
StringBuffer sb = new StringBuffer();
while ((s = br.readLine())!=null){
sb.append(s+"\n");
}
str = sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return str;
}
// 文件写入
public static void writerBuffer(String str,String path,boolean isAppend){
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(path,isAppend);
bw = new BufferedWriter(fw);
bw.write(str);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二进制读取、写入
二进制文件的读取可以用:DataInputStream、DataOutputStream,其的使用方法与InputStreamReader和OutputStreamWriter类似
示例:
用DataInputStream、DataOutputStream实现二进制文件复制
public static void copyData(String fromPath,String toPath){
FileInputStream fis = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
fis = new FileInputStream(fromPath);
dis = new DataInputStream(fis);
byte[] b = new byte[fis.available()];
dis.read(b);
fos = new FileOutputStream(toPath);
dos = new DataOutputStream(fos);
dos.write(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
dos.close();
fis.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化和反序列化
序列化是将对象的状态写入到特定的流中的过程
反序列化则是从特定的流中获取数据重新构建对象的过程
实现序列化、反序列化的步骤
写对象:
1、要求对象的类型必须是可序列化的类型(实现Serializable接口)
2、先有写入的目标流
3、创建对象流,把输出流装入
4、调用对象流的writeObject()把对象装入
5、关闭资源
读对象:
1、先有输入的源文件流
2、创建对象输入流,装入文件输入流
3、调用对象流的readObject()读取到对象
4、关闭资源
示例:
// Student类,实现Serializable接口
public class Student implements Serializable {// 此接口声明该类可以序列化
private int stuId;
private String name;
private String sex;
private Date birthday;
public Student() {
}
public Student(int stuId, String name, String sex, Date birthday) {
this.stuId = stuId;
this.name = name;
this.sex = sex;
this.birthday = birthday;
}
public int getStuId() {
return stuId;
}
public void setStuId(int stuId) {
this.stuId = stuId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
// 测试类,实现序列化、反序列化
public class TestObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 序列化
Student s = new Student(1,"张三","男",new Date());
FileOutputStream fos= new FileOutputStream("obj.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
// 反序列化
FileInputStream fis = new FileInputStream("obj.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
Student stu = (Student)obj;
}
}