IO流汇总

IO流知识汇总

前导:IO流看起来比较多比较杂,但用法就那几样,记住怎么用就好,学习时注意各个流的继承关系。

含义

注意:站在程序的角度

I:In ,输入流,read读取(读取文件中的数据)

O:Out,输出流,writer写入(向文件里写入数据)

流:一点点的读取或者写入

IO流分类

按照方向分:输入流、输出流

按照单位分:字节流、字符流

按照功能分:节点流/基础流、处理流

File

File类在创建时(用构造方法时) 存的 只是一个目录路径或文件路径,实际就是一字符串,而不会去管你这个路径是不是存在的。

File类有创建目录、文件的方法,在用这些方法时才考虑路径是否存在。

1. File概述、构造方法

File :它是文件的目录路径名的抽象表示

  • ​ 文件和目录是可以通过File封装的
  • 对于File而言,其封装的并不是一个真正的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的。

构造方法:

​ 其构造方法有4种,这里只写了3种,具体查API

构造方法名说明
File(String pathname)通过将给定的路径名字字符串转换为抽象路径名来创建新的File实例
File(String parent, String child)从父路径名字符串和子路径名字符串创建新的File实例
File(File parent, String child)从父抽象路径名和子路径名字符串创建新的File实例
File f1 = new File("D:\\cat_vc\\Java.txt");
//文件路径中的"\\"有一个是转义字符,所以其实只有一个斜杠
System.out.println(f1);
File f2 = new File("D:\\cat_vc", "Java.txt");
File f3 = new File("D:\\cat_vc");
File f4 = new File(f3, "Java.txt");

2. File创建文件或目录

方法名说明
public boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径命名的新空文件
public boolean mkdir()创建由此抽象路径命名的目录
public boolean mkdirs()创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
File f1 = new File("D:\\cat_vc\\Java.txt");
System.out.println(f1.createNewFile());
//文件目录不存在会报错
//目录存在--文件不存在,创建文件返回true
//目录存在--文件存在,不创建,返回false

File f2 = new File("D:\\cat_vc\\JavaSE");
System.out.println(f2.mkdir());
//目录不存在,创建目录返回true
//目录存在,不创建,返回false
//其父目录不存在不会报错,但也不会创建成功
File f3 = new File("D:\\cat_vc\\JavaWEB\\H5");
System.out.println(f3.mkdirs());
//创建目录,父目录不存在就补全

File f3 = new File("D:\\cat_vc\\JavaWEB\\H5\\java.txt");
System.out.println(f3.mkdirs());
//这玩意创建的java.txt是目录不是文件

3.File类的判断和获取功能

方法名说明
public boolean isDirectory()测试此抽象路径名表示的File是否为目录
public boolean isFile()测试此抽象路径名表示的File是否为文件
public boolean exists()测试此抽象路径名表示的File是否存在
public String getAbsolutePath()返回此抽象路径名的绝对路径名字符串
public String getPath()将此抽象路径名转换为路径名字符串
public String getName()返回由此抽象路径名表示的文件或目录的名称
public String[] list()返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
public File[] listFiles()返回此抽象路径名表示的目录中的文件和目录的File对象数组
System.out.println("是否可读:"+file.canRead());
System.out.println("是否可写:"+file.canWrite());
System.out.println("是否隐藏:"+file.isHidden());
System.out.println("获取文件的长度(字节):"+ file.length());

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("最后修改时间:" + sdf.format(file.lastModified()));

4. File删除功能

方法名说明
public boolean delete()删除由此抽象路径名表示的文件或目录

目录下如果还有文件或子目录是删除不掉该目录的,要删除一个大文件夹,要使用递归从最底层删起走

案例 – 创建文件

需求:在不知道父目录是否存在的情况下创建文件

File file = new File("D:\\cat_vc\\JavaWEB\\H5\\javaee.txt");
//获取父目录
File parentFile = file.getParentFile();
if(!parentFile.exists()){//文件夹不存在
    parentFile.mkdirs();
}
file.createNewFile();

案例 – 删除文件夹

需求:删除一个文件夹下的所有内容(用递归完成)

准备:随便在哪儿复制一个大小100、200 M左右的文件夹,放在指定路径(自己设定,就删这玩意)

public static void main(String[] args) {
    File file = new File("D:\\cat_vc");
    method(file);
}
public static void method(File file){
    File[] listFiles = file.listFiles();
    for (File f : listFiles) {
        if(f.isDirectory()){//文件夹
            method(f);
            f.delete();
        }else if(f.isFile()){//文件
            f.delete();
        }
    }
}

案例 – 输出文件夹下的所有.txt文件

public static void main(String[] args) {
   File file = new File("D:\\cat_vc");
    method(file, ".txt");
}
public static void method(File file,String str){
    File[] listFiles = file.listFiles();
    for (File f : listFiles) {
        if(f.isDirectory()){//文件夹
            method(f, str);
        }else if(f.isFile()){//文件
            String name = f.getName();
            if(name.endsWith(str)){
                System.out.println(name);
            }
        }
    }
}

字节流

注意:所有的输入流,文件不存在就报错

该抛异常的抛异常,快捷键alt + enter

1. InputStream和OutputStream

​ 字节流抽象基类

2. FileInputStream和FileOutputStream

​ 文件字节输入输出流

​ FileInputStream extends InputStream;

​ FileOutputStream extends OutputStream

//创建流对象,覆盖写
FileOutputStream fos = new FileOutputStream("io.txt");//相对路径是写到项目路径下的
//追加写
//FileOutputStream fos = new FileOutputStream("io.txt",true);

//fos.write(97);//写入ASCII
//fos.write("123abc".getBytes());//写入字节数组
fos.write("123abc".getBytes(),2,3);//写入字节数组,偏移量,写入字节个数
//3.关流
fos.close();
FileInputStream fis = new FileInputStream("io.txt");
//int read = fis.read();//读取第一个字节,返回ASCII
//System.out.println(read);

//int read;
//while((read=fis.read()) != -1){//read()依次读取单个字节
//    System.out.print((char)read);
//}

byte[] bs = new byte[1024];
int len;
while((len = fis.read(bs)) != -1){//一次读入字节数组长度,提高效率
    System.out.println(new String(bs, 0, len));
}
//关流
fis.close();

3. FilterInputStream和FilterOutputStream

​ 过滤器字节输入输出流,少用。

​ FilterInputStream extends InputStream;

​ FilterOutputStream extends OutputStream

4. BufferedInputStream和BufferedOutputStream

​ 带有缓冲区的字节输入输出流,效率高。默认缓冲区大小:8192字节,8192字节是8KB。

​ BufferedInputStream extends InputStream;

​ BufferedOutputStream extends OutputStream

//使用默认的缓冲区(大小:8192个字节)
//BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("io.txt"));
//自定义长度的缓冲区(大小:10000个字节)
//BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("io.txt"), 10000);
//在文件末尾追加数据
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("io.txt",true));

bos.write("123abc".getBytes());
bos.close();
//默认缓冲区大小:8192个字节
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("io.txt"));
//自定义缓冲区大小:10000字节
//BufferedInputStream bis = new BufferedInputStream(new FileInputStream("io.txt"),10000);

byte[] bs = new byte[1024];
int len;
while((len = bis.read(bs)) != -1){
    System.out.println(new String(bs, 0, len));
}
bis.close();
//try...catch的方式
//复制文件
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
    bis = new BufferedInputStream(new FileInputStream("柯南小学生.mp4"));
    bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
    
    byte[] bs = new byte[1024];
    int len;
    while((len = bis.read(bs)) != -1){
        bos.write(bs, 0, len);
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}finally{

    if(bis != null){
        try {
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if(bos != null){
        try {
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符流

1. Reader 和Writer

​ 字符流的抽象基类

2. InputStreamReader 和OutputStreamWriter

​ 字符输入输出转换流(字节流转换字符流)

​ 应用场景:获取到的流是字节流,但是要去做字符操作

​ 注意:使用转换流都加编码格式

​ InputStreamReader extends Reader;

​ OutputStreamWriter extends Writer

//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("io.txt"));
//设置编码格式
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("io.txt"),"GBK");
//设置编码格式 + 在文件末尾追加内容
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("io.txt",true),"GBK");

//osw.write(97);//写入ASCII
//osw.write("柯南小可爱,皇冠给你带~~~");//写入字符串
//osw.write("柯南小可爱,皇冠给你带~~~", 2, 9);//写入字符串,偏移量,写入字符个数
//osw.write("柯南小可爱,皇冠给你带~~~".toCharArray());//写入字符数组
osw.write("柯南小可爱,皇冠给你带~~~".toCharArray(),2,9);//写入字符数组,偏移量,写入字符个数
osw.close();
//InputStreamReader isr = new InputStreamReader(new FileInputStream("io.txt"));
//设置编码格式
InputStreamReader isr = new InputStreamReader(new FileInputStream("io.txt"),"GBK");

//读取数据 一个字符一个字符的读取
//int read;
//while((read = isr.read()) != -1){
//    System.out.println((char)read);
//}

char[] cs = new char[1024];
int len;
while((len = isr.read(cs)) != -1){
    System.out.println(new String(cs, 0, len));
}
isr.close();
//拷贝文件
InputStreamReader isr = new InputStreamReader(new FileInputStream("小说.txt"), "GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("copy.txt"), "GBK");

char[] cs = new char[1024];
int len;
while((len = isr.read(cs)) != -1){
    osw.write(cs, 0, len);
}
isr.close();
osw.close();

3. FileReader 和FileWriter

​ 文件字符输入输出流

​ FileReader extends InputStreamReader;

​ FileWriter extends OutputStreamWriter

//FileWriter fw = new FileWriter("io.txt");
//在文件末尾追加内容
FileWriter fw = new FileWriter("io.txt",true);
fw.write("柯南小可爱,皇冠给你带~~~".toCharArray());
fw.close();
FileReader fr = new FileReader("io.txt");	
char[] cs = new char[1024];
int len;
while((len = fr.read(cs)) != -1){
    System.out.println(new String(cs, 0, len));
}
fr.close();
//拷贝文件
FileReader fr = new FileReader("小说.txt");
FileWriter fw = new FileWriter("copy.txt");
char[] cs = new char[1024];
int len;
while((len = fr.read(cs)) != -1){
    fw.write(cs, 0, len);
}
fr.close();
fw.close();

4. BufferedReader 和BufferedWriter

​ 带有缓冲区的字符输入输出流,默认缓冲区大小:8192字符

​ BufferedReader extends Reader;

​ BufferedWriter extends Writer

//默认缓冲区:8192字符	(FileWriter->BufferedWriter)
//BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt"));
//自定义缓冲区:10000	(FileWriter->BufferedWriter)
//BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt"),10000);
//在文件末尾追加		(FileWriter->BufferedWriter)
//BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt",true));

//(FileOutputStream -> OutputStreamWriter -> BufferedWriter)
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("io.txt"), "GBK"));

bw.write("柯南小可爱,皇冠给你带~~~".toCharArray());
bw.close();
BufferedReader br = new BufferedReader(new FileReader("io.txt"));
//BufferedReader br = new BufferedReader(new FileReader("io.txt"),10000);
//	(FileInputStream -> InputStreamReader -> BufferedReader)
//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("io.txt"),

//读取数据 一行一行的读取
//String line;
//while((line = br.readLine()) != null){
//    System.out.println(line);
//}

char[] cs = new char[1024];
int len;
while((len = br.read(cs)) != -1){
    System.out.println(new String(cs, 0, len));
}
br.close();
BufferedReader br = new BufferedReader(new FileReader("小说.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));
char[] cs = new char[1024];
int len;
while((len = br.read(cs)) != -1){
    bw.write(cs, 0, len);
}
br.close();
bw.close();
BufferedReader br = new BufferedReader(new FileReader("小说.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));
String line;
while((line = br.readLine()) != null){
    bw.write(line);
    bw.newLine();//换行
}
br.close();
bw.close();

各种流

对象流

ObjectInputStream 对象输入流

ObjectOutputStream 对象输入流

对象流最重要的用法就是用于存对象(存进去的东西,直接打开文件是看不懂的,取出来可以看懂就算成功)

扩展:

序列化概念:

序列化:将程序中的对象写入到文件中 — 钝化

反序列化:将文件中的对象读取到程序中 — 活化

一个类的对象要想通过对象流写入到文件中,该类就必须实现序列化接口(Serializable)

Serializable叫做序列化接口,该接口没有让我们去实现任何的方法,这种接口叫做标记型接口

transient修饰属性后,该属性不会随着对象写入到文件中

static静态属性也不会随着对象写入到文件中

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
oos.writeInt(1000);//写入int值
oos.writeDouble(123.123);//写入double值
oos.writeObject(new Date());//写入对象
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
//注意:读取顺序和写入顺序必须一致
int readInt = ois.readInt();
double readDouble = ois.readDouble();
Date date = (Date) ois.readObject();
System.out.println(readInt);
System.out.println(readDouble);
System.out.println(date);
ois.close();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
oos.writeObject(new Student("张三", '男', 21, "2231", "001"));
oos.writeObject(new Student("李四", '男', 28, "2109", "002"));
oos.writeObject(new Student("王五", '男', 20, "2123", "003"));
oos.writeObject(null);
oos.close();

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
//读取数据(注意:读取顺序和写入顺序必须一致)
Student stu;
while((stu = (Student) ois.readObject()) != null){
    System.out.println(stu);
}
ois.close();

打印流

PrintStream字节打印流

PrintWriter字符打印流

//PrintStream ps = new PrintStream("io.txt");
PrintStream ps = new PrintStream(new FileOutputStream("io.txt", true));//追加写
ps.println("兰小可爱,皇冠给你带~~~");
ps.close();
//PrintWriter pw = new PrintWriter("io.txt");
//PrintWriter pw = new PrintWriter(new FileOutputStream("io.txt", true));
PrintWriter pw = new PrintWriter(new FileWriter("io.txt", true));
pw.println("林2小可爱,皇冠给你带~~~");
pw.close();

扩展:重定向问题

//重定向 System.in
//重定向:(方向:文件->程序)
System.setIn(new FileInputStream("io.txt"));
//获取的是重定向后的InputStream
InputStream in = System.in;
Scanner scan = new Scanner(in);
String str = scan.next();
System.out.println(str);
scan.close();
//重定向 System.out
//重定向:(方向:程序->文件)
System.setOut(new PrintStream(new FileOutputStream("io.txt",true)));
//获取重定向的输出流
PrintStream out = System.out;
out.println("哈哈哈哈");

随机访问流

随机访问流并不是说就真的随机访问了

RandomAccessFile w = new RandomAccessFile("io.txt", "rw");
w.write("123abc木头人".getBytes());
w.close();
//在文件末尾追加内容
File file = new File("io.txt");
RandomAccessFile w = new RandomAccessFile(file, "rw");
//设置指针在文件末尾
w.seek(file.length());//填数字是指定位置开始写
w.write("123abc木头人".getBytes());
w.close();
RandomAccessFile r = new RandomAccessFile("io.txt", "r");
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
    System.out.println(new String(bs, 0, len));
}
r.close();
//断点续传--网断了连上接着之前的位置下,而不是重新开始
RandomAccessFile r = new RandomAccessFile("水野朝阳.mp4", "r");
File file = new File("copy.mp4");
RandomAccessFile w = new RandomAccessFile(file, "rw");
//设置指针
r.seek(file.length());
w.seek(file.length());
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
    w.write(bs, 0, len);
}
r.close();
w.close();

内存流

内存流是程序到内存,但程序本身就是在内存里边的,内存流用处不大,也关不掉

//创建内存输入流(创建流时就将数据放入到内存中)
ByteArrayInputStream bis = new ByteArrayInputStream("123abc".getBytes());
//获取数据
byte[] bs = new byte[1024];
int len;
while((len = bis.read(bs)) != -1){
    System.out.println(new String(bs, 0, len));
}
//创建内存输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//写入数据
baos.write("123ABC木头人".getBytes());
//一次性读取数据
System.out.println(baos.toString());
System.out.println(new String(baos.toByteArray()));

注:考虑效率用带缓存的流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cat_lkh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值