今天就来讲讲java的io流,在开发中用到的地方还很多,比如文件上传,文件下载,文件解压缩等等都应用到了,所以这块知识还是挺重要的。
首先说流之间,说下File类,它是文件和目录路径名的抽象表示,也就是文件和目录是可以通过File封装成对象的,对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已,他可以是存在的,也可以是不存在的,将来是要通过具体的操作把这个路径的内容转换为具体存在的。
File类常用构造方法:
我们来测试下接口:
//File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
File f = new File("D:\\suxiaoxiao\\sisi.txt");
System.out.println(f);
//File(String parent,String child):从父路径名字符串和子路径名字符串创建新的File实例
File f = new File("D:\\suxiaoxiao","sisi.txt");
System.out.println(f);
//File(File parent,String child):从父抽象路径名和子路径名字符串创建新的File实例
File file = new File("D:\\suxiaoxiao");
File f = new File(file, "sisi.txt");
System.out.println(f);
上面的都是些路径表示的抽象方法,我们接下来讲讲File类的创建功能:
//boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
//我要在suxiaoxiao文件下创建一个sisi.txt文件,如果有就返回fasle,如果没有就返回true
File file = new File("D:\\suxiaoxiao\\sisi.txt");
file.createNewFile();
//boolean mkdir(): 在D:\suxiaoxiao目录下创建一个sisi.txt目录
File file = new File("D:\\suxiaoxiao\\sisi.txt");
System.out.println(file.mkdir());
//boolean mkdirs(): 在D:\suxiaoxiao目录下创建多级目录
File file = new File("D:\\suxiaoxiao\\beautifulgril\\sisi.txt");
System.out.println(file.mkdirs());
File类判断和获取功能
判断方法:
获取功能
//创建一个File
File file = new File("D:\\suxiaoxiao\\beautifulgril\\sisi.txt");
//测试此抽象路径名表示的File是否为目录
System.out.println(file.isDirectory());
//测试此抽象路径名表示的File是否为文件
System.out.println(file.isFile());
//测试此抽象路径名表示的File是否存在
System.out.println(file.exists());
//创建一个File
File file = new File("D:\\suxiaoxiao\\beautifulgril\\sisi.txt");
//返回此抽象路径名的绝对路径名字符串
System.out.println(file.getAbsolutePath());
//将此抽象路径名转换为路径名字符串
System.out.println(file.getPath());
//返回由此抽象路径名表示的文件或目录的名称(就是返回最后一个目录或文件)
System.out.println(file.getName());
//创建一个File
File file = new File("D:\\suxiaoxiao");
//public String[] list(); 返回此抽象路径名表示的目录的文件和目录的名称字符串数组(就是返回该文件夹下的所有文件和文件夹字符数组)
String[] list = file.list();
for (String s : list) {
System.out.println(s);
}
//创建一个File
File file = new File("D:/agricultural");
//public File[] list(); 返回此抽象路径名表示的目录的文件和目录的File对象数组(返回的是文件夹或文件的绝对路劲)
File[] list = file.listFiles();
for (File s : list) {
System.out.println(s);
}
File类删除功能:
//创建一个File
File file = new File("D:\\suxiaoxiao\\beautifulgril\\sisi.txt");
//删除sisi.txt
file.delete();
说完文件,和文件夹,我们来说下递归,毕竟文件假和文件是分层级的,这个时候就需要用到递归,递归可以理解为剥洋葱,一层一层的去递归,直到找到自己的文件。
递归的介绍:
以编程的角度看,递归指的是方法定义中调用方法本身的现象,可以理解为自己调用自己。
我们来举个例子:
求1到n的和
/**
* 定义一个静态方法 参数是n
* @return
*/
private static int getSum(int n) {
if(n==1){
return 1;
}
else{
return n+getSum(n-1);
}
}
//求1到n的和
int sum = getSum(5);
System.out.println(sum);
我们来用递归完成便利某目录下的所有内容,并把所有文件的绝对路径输出在控制台:
我想得到IDEA下面所有的文件路径:
public static void main(String[] args) throws IOException {
File file = new File("D://IDEA");
getFilePath(file);
}
private static void getFilePath(File file) {
//获取给定的File目录下所有的文件或者目录的File数组
File[] filesArray = file.listFiles();
//便利该File数组,得到每一个File对象
if(filesArray != null){
//如果不为空,判断该File是否是目录
for (File f : filesArray) {
//判断该File对象是否是目录
if(f.isDirectory()){
//是:递归调用
getFilePath(f);
} else{
//不是:获取绝对路径输出在控制台
System.out.println(f.getAbsolutePath());
}
}
}
}
File类说完了,我们来正式说说IO流:
IO流概述和分类
IO流介绍:输入和输出 对应Input和Output
流是一种概念,是对数据传输的总称,也就是数据在设备间的传输称为流,流的本质是数据传输。
IO流就是用来处理设备间数据传输问题的,常见的应用:文件复制,文件上传,文件下载,比如迅雷下载东西。
IO流的分类;
按照数据的流向:
输入流:读数据
输出流:写数据
按照数据类型来分:
字节流:
字节输入流
字节输出流
字符流
字符输入流
字符输出流
IO流使用的场景
如果操作的是纯文本文件,优先使用字符流
如果操作的是图片,视屏,音频等的二进制文件,优先使用字节流
不如在不确定文件类型的情况下,优先使用字节流,因为字节流是没有什么搞不定的,俗称万能流。
我们来说下这个万能的字节流:
字节流写数据:
字节流抽象基类:
InputStream;这个抽象类是表示字节输入流的所有类的超类,可以理解为所有字节输入流的祖宗
OutputStream:这个抽象类是表示字节输出流的所有类的超类,
子类名特点;子类名称都是以其父类名作为子类名的后缀
字节输出流:FileOutPutStream(String name):创建文件输出流以指定的名称写入文件
使用字节输出流写数据的步骤:
创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
调用字节输出流对象的写数据方法
释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
我们来用代码演示下:
public static void main(String[] args) throws Exception {
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\suxiaoxiao\\sisi.txt");
//void write():将指定的字节写入此文件输出流
fos.write(12);
fos.write(16);
fos.write(16);
//释放资源
fos.close();
}
字节流写数据的三种方式
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\suxiaoxiao\\sisi.txt");
//void write(byte[] b):将b.lengeth字节从指定的字节数组写入此文件输出流
byte[] bys = {97,98,99,100};
fos.write(bys);
fos.close();
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\suxiaoxiao\\sisi.txt");
//void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从 偏移量off开始写入此文件输出流
byte[] bys = "abcdefg".getBytes();
fos.write(bys,1,3);
fos.close();
字节流写数据问题总结:
如何实现换行了:windows:\r\n linux\:n
我们在想一个问题,我们怎么实现追加写入了,比如abc后面追加一个d
public FileOutputStream(String name,boolean append)
创建文件输出流以指定的名称写入文件,如果第二个参数为true,则字节将写入文件的末尾而不是开头
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\suxiaoxiao\\sisi.txt",true);
//void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从 偏移量off开始写入此文件输出流
fos.write(100);
fos.close();
一般在开发中,我们都是使用Try-catch-finally来处理流操作
finally特点:
被finally控制的语句一定会执行,除非jvm退出
//创建字节输出流对象
FileOutputStream fos = null;
try {
fos = new FileOutputStream("D:\\suxiaoxiao\\sisi.txt",true);
fos.write(100);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}