
JAVA-IO流
IO 流
流的概念
内存与存储设备之间传输数据的通道
流的分类
按方向【重点】
输入流:将<存储设备>中的内容读到<内存>中;
输出流:将<内存>中的内容写到<存储设备>中;
文件 ———输入流———–> 程序 ———输出流———–>文件
按单位
- 字节流:以字节流为单位,可以读写所有数据;
- 字符流:以字符为单位,只能读写文本数据;
按功能
- 节点流:具有实际传输数据的读写功能;
- 过滤流:在节点流的基础之上增强功能;
字节流
字节流的父类(抽象类):
InputStream 字节输入流
//InputStream 字节输入流 public int read(){} public int read(byte[] b){} public int read(byte[] b, int off, int len){}
OutStream 字节输出流
// OutputStream 字节输出流 public void write(int n){} public void write(byte[] b){} public void write(byte[] b, int off, int len){}
文件字节流
输入流:
// 创建文件输出流对象
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA- workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
// 单个字节读取文件
int data = 0;
while ((data=fis.read()) != -1) {
System.out.print((char) data);
}
// 指定读取个数,每次三个
byte[] buf = new byte[3];
int count = fis.read(buf);
System.out.println(new String(buf));
System.out.println(count);
int count2 = fis.read(buf);
System.out.println(new String(buf));
System.out.println(count2);
// 循环读取
byte[] buf = new byte[1024];
int count = 0;
while ((count=fis.read(buf))!=-1) {
System.out.println(new String(buf, 0, count));
}
//关闭
fis.close();
输出流:
//创建文件输出流对象;
FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\bbb.txt");
//写入文件
fos.write(97);
fos.write('b');
fos.write('c');
//写入字符串
String str = "helloworld";
fos.write(str.getBytes());
fos.close();
图片复制案例
//创建流
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.jpg");
FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\ccc.jpg");
////边读边写
byte[] b = new byte[1024];
int count = 0;
while ((count = fis.read(b)) != -1) {
fos.write(b, 0, count);
}
//关闭
fis.close();
fos.close();
字节缓冲流
缓冲流:BufferedInputStream/ BufferedOutputStream
提高 IO 效率,减少访问磁盘次数;
数据存储在缓冲区中,flush 是将缓冲区的内容写入文件中,也可以直接 close
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
//创建缓冲流对象
BufferedInputStream bis = new BufferedInputStream(fis);
//读取
int data = 0;
while ((data=bis.read())!=-1){
System.out.print((char) data);
}
//关闭
bis.close();
fis.close();
缓冲流读文件:
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
//创建缓冲流对象
BufferedInputStream bis = new BufferedInputStream(fis);
//读取
// int data = 0;
// while ((data=bis.read())!=-1){
// System.out.print((char) data);
// }
byte[] buf = new byte[1024];
int count = 0;
while ((count = bis.read(buf))!=-1) {
System.out.print(new String(buf, 0, count));
}
//关闭
bis.close();
fis.close();
缓冲流写文件:
//创建缓冲流对象
FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\ddd.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写入文件
for (int i = 0; i < 5; i++) {
bos.write("theworllllld\n".getBytes()); //写入缓冲区,缓冲区默认大小为8k
bos.flush(); // 刷新到硬盘
}
//关闭,bos.close();会自动调用 bos.flush(), 但异常中断的话会写入失败
bos.close();
对象流
ObjectOutputStream / ObjectInputStream
- 增强了缓冲区功能
- 增强了读写 8 种基本数据类型和字符串的功能
- 增强了读写对象的功能
readObject()
从流中读取一个对象writeObject(Object obj)
向流中写入一个对象
使用流传输对象的过程称为序列化(写入)、反序列化(读取)
序列化
// 1. 创建对象流
FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\st.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 2. 序列化(写入操作)
Student zhangsan = new Student("zs", 20);
oos.writeObject(zhangsan);
// 3. 关闭
oos.close();
反序列化
// 1. 创建对象流
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\st.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
// 2. 读取文件(反序列化)
Student s = (Student)ois.readObject();
// 3. 关闭
ois.close();
注意事项:
- 某个类要想序列化必须实现 Serializable 接口;
- 序列化类中对象属性要求实现 Serializable 接口;
- 序列化版本号 ID
例如 :private static final long serialVersionUID = -8318741215394696905L;
,保证序列化的类和反序列化的类是同一个类; - 使用 transient 修饰属性,这个属性就不能序列化;
- 静态属性不能序列化;
- 序列化多个对象,可以借助集合来实现;
字符流
// 传统字节流读取
public static void main(String[] args) throws Exception {
// 1. 创建FileInputStream对象
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
// 2. 读取
int data = 0;
while((data = fis.read()) != -1){
System.out.print(((char)data));
}
// 3. 关闭
fis.close();
}
字符流的父类
reader
字符输入流
public int read(){}
public int read(char[] c){}
public int read(char[] b, int off, int len){}
public static void main(String[] args) throws Exception {
// 1. 创建FileReader 文件字符输入流
FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
// 2. 读取
// 2.1 单个字符读取
int data = 0;
while((data = fr.read()) != -1){
System.out.print((char)data);// 读取一个字符
}
char[] buf = new char[2];// 字符缓冲区读取
int count = 0;
while((count = fr.read(buf)) != -1){
System.out.print(new String(buf, 0, count));
}
// 3. 关闭
fr.close();
}
Writer
字符输出流
public void write(int n){}
public void write(String str){}
public void write(char[] c){}
public static void main(String[] args) throws Exception {
// 1. 创建FileWriter对象
FileWriter fw = new FileWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
// 2. 写入
for(int i = 0; i < 10; i ++){
fw.write("写入的内容");
fw.flush();
}
// 3. 关闭
fw.close();
System.out.println("执行完毕");
}
案例(使用上述方法进行文本复制)
不能复制图片或二进制文件,使用字节流可以复制任意文件
public static void main(String[] args) throws Exception{
// 1. 创建
FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
FileWriter fw = new FileWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
// 2. 读写
int data = 0;
while((data = fr.read()) != -1){
fw.write(data);
fw.flush();
}
// 3. 关闭
fw.close();
fr.close();
}
字符缓冲流
BufferedReader / BufferedWriter
高效读写、支持输入换行符、可一次写一行读一行;
public static void main(String[] args) throws Exception {
// 创建缓冲流
FileReader fr = new FileReader("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\aaa.txt");
BufferedReader br = new BufferedReader(fr);
// 读取
// 1. 第一种方式
char[] buf = new char[1024];
int count = 0;
while((count = br.read(buf)) != -1){
System.out.println(new String(buf, 0, count));
}
// 2. 第二种方式 一行一行读取
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
// 关闭
br.close();
}
PrintWriter
- 向文件中写入内容;
- 封装了
print() / println()
方法 支持写入后换行; - 支持数据原样打印;
public static void main(String[] args) throws FileNotFoundException {
// 1 创建打印流
PrintWriter pw = new PrintWriter("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
// 2 打印
pw.println(12);
pw.println(true);
pw.println(3.14);
pw.println('a');
// 3 关闭
pw.close();
}
转换流
- 桥转换流
InputStreamReader / OutputStreamWriter
- 可将字节流转换为字符流
- 可设置字符的编码方式
public static void main(String[] args) throws Exception {
// 1 创建InputStreamReader对象
FileInputStream fis = new FileInputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
// 2 读取文件
int data = 0;
while((data = isr.read()) != -1){
System.out.print((char)data);
}
// 3 关闭
isr.close();
}
public static void main(String[] args) throws Exception {
// 1 创建OutputStreamReader对象
FileOutputStream fos = new FileOutputStream("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\fff.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
// 2 写入
for (int i = 0; i < 10; i++) {
osw.write("写入内容\n");
osw.flush();
}
// 3 关闭
osw.close();
}
File 类
概念:代表物理盘符中的一个文件或者文件夹
分隔符
//分隔符
public static void separator() {
System.out.println("路径分隔符" + File.pathSeparator);
System.out.println("名称分隔符" + File.separator);
}
文件操作
//文件操作
public static void fileOpen() throws Exception {
//创建文件
File file = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\file.txt");
if (!file.exists()) {
boolean b = file.createNewFile();
System.out.println("创建结果" + b);
}else {
System.out.println("文件已存在");
}
//删除文件-直接删除
// System.out.println(file.delete());
//删除文件 jvm退出时删除
// file.deleteOnExit();
// Thread.sleep(5000);
//获取文件绝对路径
System.out.println("文件绝对路径:" + file.getAbsolutePath());
//获取写的路径
System.out.println(file.getPath());
//获取文件名称
System.out.println(file.getName());
//获取父目录
System.out.println(file.getParent());
//获取文件长度
System.out.println(file.length());
//获取文件创建时间
System.out.println(new Date(file.lastModified()).toLocaleString());
//判断
//是否可写
//System.out.println(file.canWrite()); //linux支持
//是否可读
System.out.println(file.canRead());
//是否是文件
System.out.println(file.isFile());
//是否隐藏
System.out.println(file.isHidden());
}
文件夹操作
//文件夹操作
public static void directoryOpe() throws Exception{
File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa\\bbb\\ccc");
System.out.println(dir.toString());
if (!dir.exists()) {
//创建单级目录
// dir.mkdir();
//创建多级目录
System.out.println("创建结果" + dir.mkdirs());
}
//删除文件
//直接删除
// System.out.println(dir.delete()); //只能删除空目录
//使用jvm删除
// dir.deleteOnExit();
// Thread.sleep(3000);
//获取文件夹信息
//获取绝对路径
System.out.println(dir.getAbsolutePath());
//获取路径
System.out.println(dir.getPath());
//获取名称
System.out.println(dir.getName());
//获取父目录
System.out.println(dir.getParent());
//获取创建时间
System.out.println(new Date(dir.lastModified()).toLocaleString());
//判断
//是否是文件夹
System.out.println(dir.isDirectory());
//是否隐藏
System.out.println(dir.isHidden());
//遍历文件夹
File dir2 = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file");
String[] dirs = dir2.list();
//File[] dirs2 = dir2.listFiles();
for (String s : dirs) {
System.out.println(s);
}
FileFilter
// fileFilter接口使用,定制方法遍历
public static void main(String[] args) {
File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa\\bbb\\ccc");
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".bin")){
return true;
}
return false;
}
});
for (File file : files) {
System.out.println(file.getName());
}
}
递归遍历文件夹
遍历多级文件夹下的文件
public static void main(String[] args) {
File dir = new File("D:\\workspace\\IDEA-workspace\\kuangshen_java\\IO流\\src\\com\\file\\aaa");
listDir(dir);
}
public static void listDir(File dir) {
File[] files = dir.listFiles();
if (files != null && files.length>0) {
for (File file : files) {
if (file.isDirectory()){
listDir(file);
}else {
System.out.println(file.getAbsolutePath());
}
}
}
}
递归删除文件夹
删除多级文件夹下的文件
public static void delDir(File dir) {
File[] files = dir.listFiles();
if (files != null && files.length>0) {
for (File file : files) {
if (file.isDirectory()){
delDir(file);
}else {
System.out.println(file.getAbsolutePath() + "删除文件" + file.delete());
}
}
}
}