【Java学习系列】Java高级之输入和输出处理(二)
Reader类
- Reader类常用方法
- int read()
- int read(char[] c)
- read(char[] c, int off, int len)
- void close()
- 子类InputStreamReader常用的构造方法
- InputStreamReader(InputStream in)
- InputStreamReader(InputStream in, String charsetName)
FileReader类
- FileReader类是InputStreamReader的子类
- FileReader(File file)
- FileReader(String name)
- 该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型
- System.out.println(System.getProperty(“file.encoding”));获得本地平台的字符编码类型
使用FileReader读取文件
- 与字节流FileInputStream类实现文本文件读取步骤类似
- 1、引入相关的类
import java.io.Reader;
import java.io.FileReader;
import java.io.IOException;
- 2、创建FileReader对象
Reader fr = new FileReader("D:/myDoc/简介.txt");
- 3、读取文本文件的数据
fr.read();
- 4、关闭相关的流对象
fr.close();
示例
/**
*
* @author
* 字符流 读取
*
*/
public class Lx1 {
/**
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Reader rd = null;
//设置字符流读取文件
try {
rd = new FileReader("1.txt");
//给定一个char[]接收读取到的字符
char[] ch = new char[1024];
//用read()方法读取到char[]中的字符数据
rd.read(ch);
//给定一个String类型将读到的数据变成字符串
String str = new String(ch);
//打印并用trim()清除空格
System.out.println(str.trim());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//关闭流
try {
rd.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
BufferedReader类
- 如何提高字符流读取文本文件的效率
- 使用FileReader类与BufferedReader类
- BufferedReader类是Reader的子类
- BufferedReader类带有缓冲区
- 按行读取内容的readLine()方法
- BufferedReader常用的构造方法
- BufferedReader(Reader in)
- 子类BufferedReader特有的方法
- readLine()
使用BufferedReader读文本文件
- 引入相关的类
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
- 构造BufferedReader对象和FileReader对象
Reader fr = new FileReader("C:\\myTest.txt ");
BufferedReader br = new BufferedReader(fr);
- 调用readLine()方法读取数据
br.readLine();
- 关闭文件流对象
br.close();
fr.close();
解决读取时中文乱码
FileInputStream fis=new FileInputStream("c:\\myDoc\\hello.txt");
//使用 InputStreamReader 并设置编码格式
InputStreamReader fr=new InputStreamReader(fis,"UTF-8");
BufferedReader br=new BufferedReader(fr);
示例
/**
*
* @author
* 字符流 读取 缓冲
*
*/
public class Lx11 {
/**
*
* @param args
*/
public static void main(String[] args) {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
//设置字符流读取文件
try {
is = new FileInputStream("1.txt");
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
//读取文件
String msg;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//关闭流
try {
is.close();
isr.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Writer类
- 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类
- FileWriter类是OutputStreamWriter的子类
- FileWriter (File file)
- FileWriter (String name)
- 该类只能按照本地平台的字符编码来写数据,用户不能指定其他的字符编码类型
使用FileWriter写文件
- 与字节流FileOutputStream类实现向文本文件写入数据步骤类似
- 1、引入相关的类
import java.io.Reader;
import java.io.FileWriter;
import java.io.IOException;
- 2、创建FileReader对象
Writer fw = new FileWriter("D:\\myDoc\\简介.txt");
- 3、写文本文件
fw.write();
- 4、关闭相关的流对象
fw.close();
示例
/**
*
* @author
* 字符流 写入
*
*/
public class Lx2 {
/**
*
* @param args
*/
public static void main(String[] args) {
Writer wt = null;
//设置字符流写入文件
try {
wt = new FileWriter("1.txt");
//写入文件
wt.write("李四");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//关闭流
try {
wt.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
BufferedWriter类
- 如何提高字符流写文本文件的效率
- 使用FileWriter类与BufferedWriter类
- BufferedWriter常用的构造方法
- BufferedWriter(Writer out)
- BufferedWriter类是Writer类的子类
- BufferedWriter类带有缓冲区
使用BufferedWriter写文件
- 引入相关的类
import java.io.FileWriter ;
import java.io.BufferedWriter ;
import java.io.IOException;
- 构造BufferedWriter对象和FileWriter对象
FileWriter fw = new FileWriter("C:\\myTest.txt");
BufferedWriter bw = new BufferedWriter(fw);
- 调用write()方法写数据
bw.write("hello");
- 流对象的清空和关闭flush()和close()
bw.flush();
fw.close();
示例
/**
*
* @author
* 字符流 写入 缓冲
*
*/
public class Lx22 {
/**
*
* @param args
*/
public static void main(String[] args) {
OutputStream os = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
try {
//设置字符流写入文件
os = new FileOutputStream("1.txt",true); //true设置是否追加写入文件(true:追加,false:覆盖(默认))
osw = new OutputStreamWriter(os);
bw = new BufferedWriter(osw);
//写入一个空行
bw.newLine();
//追加写入一个文件
bw.append("王五");
//刷新流(必写,否则输出的文件为空白)
bw.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
osw.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
其他例子
- 替换文本文件内容
/**
*
* @author
* 练习1:替换文本文件内容
* 按照刚才读取的模板文件pet. template的模板格式保存宠物数据到文本文件,
* 即把{name}、{type}、{master}替换为具体的宠物信息,
* 将替换后的内容写入到C:\myDoc\pet.txt中
*
*/
public class Test1 {
/**
*
* @param args
* @throws IOException
*
*/
public static void main(String[] args) throws IOException {
Reader fr = new FileReader("pet.template.txt");
BufferedReader br=new BufferedReader(fr);
String str;
String s = null;
while ((str = br.readLine()) != null){
System.out.println("替换前:" + str);
s = str.toString();
}
String newString = s.replace("{name}", "欧欧").replace("{type}", "狗狗").replace("{master}", "李伟");
Writer fw = new FileWriter("pet.txt");
System.out.println("替换后:" + newString);
fw.write(newString);
fw.close();
br.close();
fr.close();
}
}
读写二进制文件
- DataInputStream类
- FileInputStream的子类
- 与FileInputStream类结合使用读取二进制文件
- DataOutputStream类
- FileOutputStream的子类
- 与FileOutputStream类结合使用写二进制文件
使用DataInputStream读二进制文件
- 引入相关的类
import java.io.FileInputStream;
import java.io.DataInputStream;
- 构造数据输入流对象
FileInputStream fis = new FileInputStream("C:\\HelloWorld.class");
DataInputStream dis = new DataInputStream(fis);
- 调用read()方法读取二进制数据
dis.read();
- 关闭数据输入流
dis.close();
使用DataOutputStream写二进制文件
- 引入相关的类
import java.io.FileOutputStream;
import java.io.DataOutputStream;
- 构造数据输出流对象
FileOutputStream outFile = new FileOutputStream("C:\\temp.class");
DataOutputStream out = new DataOutputStream(outFile);
- 调用write()方法写二进制文件的数据
out.write();
- 关闭数据输出流
out.close();
示例
/**
*
* @author
* 练习2:复制图片
* 图片star.jpg位于C盘根目录下,要求将此图片复制到D:\myDoc\myPicture.jpg
*/
public class Test2 {
/**
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("star.jpg");
DataInputStream dis = new DataInputStream(fis);
FileOutputStream outFile = new FileOutputStream("C:/Users/Rosen/Desktop/myPicture.jpg");
DataOutputStream out = new DataOutputStream(outFile);
int num;
while ((num = dis.read()) != -1) {
out.write(num);
}
System.out.println("已完成!");
out.close();
outFile.close();
dis.close();
fis.close();
long endTime = System.currentTimeMillis();
System.out.println("耗时:" + (double)(endTime - startTime) / 1000 + "秒。");
}
}
/**
*
* @author
* 二进制流复制文件(和练习2一样,只不过写法不同(练习2为throws处理异常,这个为try-catch处理异常))
*
*/
public class Test22 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
DataInputStream dis = null;
InputStream is = null;
DataOutputStream dos = null;
OutputStream os = null;
try {
is = new FileInputStream("star.jpg");
dis = new DataInputStream(is);
os = new FileOutputStream("C:/Users/Rosen/Desktop/myPicture.jpg");
dos = new DataOutputStream(os);
int num;
while ((num = dis.read()) != -1) {
dos.write(num);
}
System.out.println("已完成!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
dos.close();
os.close();
dis.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("耗时:" + (double)(endTime - startTime) / 1000 + "秒。");
}
}
序列化和反序列化
序列化和反序列化
内存 序列化——> 流
Java对象 <——反序列化 二进制的字节序列
序列化是将对象的状态写入到特定的流中的过程
反序列化则是从特定的流中获取数据重新构建对象的过程
实现序列化
- 序列化的步骤
- 实现Serializable接口
- 创建对象输出流
- 调用writeObject()方法将对象写入文件
- 关闭对象输出流
- 注意:使用集合保存对象,可以将集合中的所有对象序列化
实现反序列化
- 反序列化的步骤
- 实现Serializable接口
- 创建对象输入流
- 调用readObject()方法读取对象
- 关闭对象输入流
- 注意:如果向文件中使用序列化机制写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取
示例
/**
*
* @author
* 练习3:学员对象的序列化和反序列化
* 需求说明
实现学员对象的序列化和反序列化
*
*/
public class Test3 {
/**
*
* @param args
*/
public static void main(String[] args) {
//new一个对象,初始化属性值
Student student = new Student("张三", 20);
OutputStream os = null;
ObjectOutputStream oos = null;
InputStream is = null;
ObjectInputStream ois = null;
try {
//反序列化student对象
os = new FileOutputStream("stu.txt");
oos = new ObjectOutputStream(os);
//将student对象写入文件
oos.writeObject(student);
//序列化student对象
is = new FileInputStream("stu.txt");
ois = new ObjectInputStream(is);
//读取文件中已写入的student对象
Student stu = (Student) ois.readObject(); //用student对象进行接收,强制转换来获得对象
//调用从文件中读入的student对象的方法
stu.show();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
ois.close();
is.close();
oos.close();
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
*
* @author
* 实现序列化
*
*/
public class Student implements Serializable{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void show() {
System.out.println("我的名字是:" + name + ",我的年龄是:" + age);
}
}