IO
本周比较专一地学习了IO流,课程把IO核心总结成了四个步奏:1、创建源;2、选择流;3、操作;4、释放资源。按照这几个步奏套用就可以完成IO流代码的核心部分内容,其他则需要自己判断修改,但是万变不离其宗,只要熟悉了用法就可以很熟练的应用。
一.基础知识部分:
在比较系统的学习IO流之前,先了解了IO流的基础知识,I就是Input;O就是Output,IO流就是文件的输入和输出流,所以这一部分内容是在与文件打交道,通过代码控制文件。
1.mkdir()与mkdirs()的区别
两者都可以用来创建指定位置和类型的文件,但是mkdir()必须保证所创建文件的上一级存在;而mkdirs()则无需,且如果上一级不存在时,可以直接把上一级也创建出来。前提:所创建的文件原来不存在,若原来存在则创建失败,用boolean判断true、false
File dir=new File("D:/eclipse-workspace/pro1/src/IO/IO.jpg");
//创建目录
boolean flag=dir.mkdirs();
System.out.println(flag);
dir =new File("D:/dir/IO/test");
flag=dir.mkdirs();
System.out.println(flag);
2.文件基本信息
File src=new File("D:/eclipse-workspace/pro1/src/IO/IO.jpg");
//基本信息
System.out.println("名称:"+src.getName()); //get名称
System.out.println("绝对路径:"+src.getAbsolutePath()); //get绝对路径
System.out.println("路径:"+src.getPath()); //get路径(相对还是绝对看自己定义的)
System.out.println("父路径:"+src.getParent()); //get父路径,上路径,上路径不存在返回0
System.out.println("父对象:"+src.getParentFile().getName());
System.out.println("###########");
//文件状态
System.out.println("是否存在:"+src.exists()); //是否存在
System.out.println("是否文件:"+src.isFile()); //是否文件
System.out.println("是否文件夹:"+src.isDirectory()); //是否文件夹
3.文件长度
//文件长度
src =new File("D:/eclipse-workspace/pro1/src/IO/IO.jpg");
System.out.println("长度"+src.length()); // 返回文件长度
src=new File("D:/eclipse-workspace/pro1/src/IO");
System.out.println("长度"+src.length()); //文件夹长度返回0
src =new File("D:/eclipse-workspace/pro1/src/IO/IO.jpg222");
System.out.println("长度"+src.length()); //不存在也返回0
System.out.println("###########");
这种方法不能直接统计文件夹下面包含的文件大小的和,也就是文件夹大小,如果想要统计,则需要另打一段方法。
public static void count(File src) {
//获取大小
if(null!=src&&src.exists()) {
if(src.isFile()) { //大小
len+=src.length();
}else { //子孙级
for(File s:src.listFiles()) {
count(s);
}
}
二、实际操作
1.输入流操作(InputStream)
//1.创建源
File src =new File("code.txt");// 相对路径,文件必须在工程下
//2.选择流
InputStream is=null;
try {
is = new FileInputStream(src);
//3.操作
int temp;
while((temp=is.read())!=-1) {
System.out.print((char)temp);//以字符输出文件code.txt里的内容
}
//4.释放资源
if(null!=is) {
is.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
输出结果就是txt文本文件里面的内容。
2.输出流操作(OutputStream)
//1.创建源
File dest =new File("dest.txt");
//2.选择流
OutputStream os =null;
try {
os = new FileOutputStream(dest,true); //追加操作,运行一次,在后面追加一次,对定义文件的操作
//3.操作
String msg ="IO is so easy\r\n"; //1.后面加的是换行 2.如果把字符串删了再运行,则就是全部删除,重新写
byte[] datas = msg.getBytes();//字符串到字节数组 编码
os.write(datas,0,datas.length);
os.flush();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.释放资源
if(null!=os) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
输出流实现了直接对文件的控制,例如上述代码,运行一次可以创建出一个名字为"code.txt"的文本文件,打开文本文件后会有"IO is so easy"的内容,且每运行一次都会换行再输出"IO is so easy",\r\n代表了换行符。
3.输入输出流综合
使用输入输出流达到文件拷贝的目的。
public static void main(String[] args) {
long t1=System.currentTimeMillis();
copy("IO.mp4","IOcopy.mp4"); //把代码拷贝出一个文本文档
long t2=System.currentTimeMillis();
System.out.println(t2-t1);
}
public static void copy(String srcPath,String destPath) { //改写成方法
//1.创建源
File src =new File(srcPath); //源头
File dest =new File(destPath); //目的地
//2.选择流
InputStream is =null;//输入流
OutputStream os =null;//输出流
try {
is = new BufferedInputStream(new FileInputStream(src)); //先打开,后关闭(这部分在后来加入了字节缓冲流,提高性能)
os = new BufferedOutputStream(new FileOutputStream(dest)); //后打开,先关闭
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//3.操作(分段读取)
byte[] flush = new byte[1024];
int len = -1;
try {
while((len=is.read(flush))!=-1) {
os.write(flush,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
//4.释放资源,分别关闭,先打开的后关闭
if(null!=os) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注:new BufferedInputStream和new BufferedOutputStream是字节缓冲流,能够大大加快效率,用的时候直接套上就行。
byte[] flush = new byte[1024]是一个缓冲容器,意思是每次1024个字节读取。
这是直接把拷贝写成了方法,然后在 main方法下直接调用,copy()方法,还必须满足后面的规定,用字符串码出路径。
程序运行后会得到一个内容与源文件一样的文件,只是名字被改变了。