目录
1、什么是IO流
2、流的分类
3、流的四大家族首领
4、java.io.*包下需要掌握的16个流
5、FileInputStream的实用方法
6、FileOutputStream的方法
7、文件复制/拷贝
8、FileReader的使用
9、FileWriter的使用
10、复制普通文本文件
11、BufferedReader带有缓冲区的字符输入流
12、节点流和包装流
13、带有缓冲区的字符输出流
14、DataOutputStream和DataInputStream数据流
15、PrintStream标准输出流
16、File类
17、练习目录拷贝
1、什么是IO流
I:Input 例如:从硬盘中读取数据进入CPU的内存
O:Output 例如:从CPU的内存读取数据进入硬盘
流:在管道(pipe line)中产生的一种计算模式
IO流:以内存为参照物,完成硬盘文件的读和写
2、流的分类
按流的方向分类:
- 输入内存(读Read),称为输入流
- 输出内存(写Write),称为输出流
按读取方式分类:
- 万能字节流,所有文件都是字节构成,例如:流 一次读取一个字节byte,等同于一次读取8个二进制
- 方便字符流,普通文本文件是由字符构成,例如:流 一次读取一个字符,且只能读取纯文本文件.txt,连word文件都无法读取(普通文本文件指的是能用记事本编辑器打开的文件,并不是都是.txt文件)
举例子:
万能字节流:
假设文件file1.txt,采用字节流读取
a中国bccc
第一次读:一个字节,正好读到 'a'
第二次读:一个字节,正好读到 '中' 字符的一半
第三次读:一个字节,正好读到 '中' 字符的另外一半
方便字符流:
假设文件file2.txt,采用字符流读取
a中国bccc
第一次读:一个字符,正好识别读到 'a
第二次读:一个字符,正好识别读到 '中'
第三次读:一个字符,正好识别读到 '国'
疑惑:java中的英文字符a不是应该占用两个字节吗?为什么读取的时候读一个字节就可以将英文字符a读出来,因为file1.txt属于windows操作系统的内容,在这个文件中,只是windows操作系统的普通文件
JAVA所有流都是在java.io.*这个包内
主要研究怎么new流对象,调用流对象的哪个方法是读,哪个方法是写
3、流的四大家族首领
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
规律:
Stream结尾的类包就是代表字节流,Reader结尾的类包就是代表字符流
四大家族的首领都是抽象类(abstract class)
四大家族的首领都实现了:java.io.Closeable接口,都有close( )方法,都是可关闭的
流的本质是在管道内流通,就占用较多的系统资源,需要养成用完流之后进行关闭流的操作的习惯 ,强行刷新清空管道中剩余未输出的数据,没有flush( )可能会导致数据丢失
四大家族的首领都实现了:java.io.Flushable接口,都有flush( )方法,都是可刷新的
4、java.io.*包下需要掌握的16个流
文件流:
java.io.FileInputStream (掌握)
java.io.FileOutputStream (掌握)
java.io.FileReader
java.io.FileWriter
转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutPutStreamWriter
缓冲流:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferInputStream
java.io.BufferedOutputStream
数据流:
java.io.DataInputStream
java.io.DataOutputStream
标准流:
java.io.PrintWriter (掌握)
java.io.PrintStream (掌握)
对象流:
java.io.ObjectInputStream (掌握)
java.io.ObjectOutputStream (掌握)
5、FileInputStream的实用方法
代码演示(从一个文件中逐个读出内容):
步骤一:新建一个文件123.txt ,复制文件路径(文件内容abc中)
步骤二:读出文件内容
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest01 {public static void main(String[] args) {FileInputStream fileInputStream = null;try {//创建文件字节输入流对象//采用绝对路径的方式:idea工具会自动把路径的单斜杠/ 转换成//双斜杠fileInputStream=new FileInputStream("D:\\2021-2022课件\\123.txt");//第一次开始读,每次只读一个字节int readData=fileInputStream.read();//看看到底读到什么东西//这个read()方法的返回值是:读取到的“字节”本身System.out.println(readData);//97//第二次读int readData2=fileInputStream.read();System.out.println(readData2);//98//第三次读int readData3=fileInputStream.read();System.out.println(readData3);//99//第四次读//读‘中’的1个字节int readData4=fileInputStream.read();System.out.println(readData4);//214//第五次读//读‘中’的另一个字节int readData5=fileInputStream.read();System.out.println(readData5);//208//第六次读//如果读取的是空,则返回-1int readData6=fileInputStream.read();System.out.println(readData6);//-1//第七次读//如果读取的是空,则返回-1int readData7=fileInputStream.read();System.out.println(readData7);//-1} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {//在finally语句块中确保流一定要关闭//关闭流的前提是:流不是空,避免空指针异常if(fileInputStream!=null){try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}}}} }
代码演示(从一个文件中循环读出内容):
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest02 {public static void main(String[] args) {FileInputStream f=null;try {f=new FileInputStream("D:\\2021-2022课件\\123.txt");//循环输出读取的数据int readData=0;while ((readData=f.read())!=-1){System.out.println(readData);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }97 98 99 214 208
代码演示(将字节数组byte[ ]读进内存):
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest02 {public static void main(String[] args) {FileInputStream f=null;try {//123.txt存储的是abcdeff=new FileInputStream("D:\\2021-2022课件\\123.txt");//定义一个byte数组,此数组一次可以存储4个字节byte[] b=new byte[4];//与read()的不同之处在于取的不是“字节”本身,而是 数量//第一次读int readData2=f.read(b);System.out.println(readData2);//4//原则:需要将‘读’的字节数组‘全部’转换成字符串类型输出System.out.println(new String(b));//abcd//实际上:需要将‘读’的字节数组‘部分’读多少转换多少System.out.println(new String(b,0,readData2));//abcd//第二次读int readData3=f.read(b);System.out.println(readData3);//2System.out.println(new String(b));//efcd//读多少转换多少System.out.println(new String(b,0,readData3));//ef//第三次读//读不到任何数据的时候返回-1int readData4=f.read(b);System.out.println(readData4);//-1//循环输出读取的数据int readData=0;while ((readData=f.read())!=-1){System.out.println(readData);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }
示意图:
代码演示(将字节数组byte[ ]读进内存,进阶循环输出):
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest03 {public static void main(String[] args) {FileInputStream f=null;try {//123.txt存储的是abcdeff=new FileInputStream("D:\\2021-2022课件\\123.txt");byte[] b=new byte[4];int readCount=0;while ((readCount=f.read(b))!=-1){System.out.print(new String(b,0,readCount));//abcdef}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }
代码演示(int available() 返回流当前剩余没有被读到的字节数量):
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest04 {public static void main(String[] args) {FileInputStream f=null;try {//123.txt存储的是abcdeff=new FileInputStream("D:\\2021-2022课件\\123.txt");//读1个字节int readByte=f.read();//还剩下可以读的字节数量System.out.println("还剩下可以读的字节数量:"+f.available());//5} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest04 {public static void main(String[] args) {FileInputStream f=null;try {//123.txt存储的是abcdeff=new FileInputStream("D:\\2021-2022课件\\123.txt");// //读1个字节 // int readByte=f.read(); // // //还剩下可以读的字节数量 // System.out.println("还剩下可以读的字节数量:"+f.available()); ////这个方法的作用:自动获取剩余的字节数量,例如:一个文件中本来有6个字节,我们就需要给一个6个字节大小的字节数组去存储,而f.available()就帮我们自动扩容到这个长度byte[] b=new byte[f.available()];int readByte2=f.read(b);//执行一次即可将文件中的abcdef全部传递到字节数组中//缺点:不适合大文件,因为byte[] 数组不可以存储大量数据System.out.println(new String(b));//abcdef} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }
代码演示(skip跳过几个字节不读取):
package com.lbj.javase.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest05 {public static void main(String[] args) {FileInputStream f=null;try {//abcdeff=new FileInputStream("D:\\2021-2022课件\\123.txt");//skip 跳过几个字节不读取f.skip(3);System.out.println(f.read());//100 直接跳到d} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}} }
6、FileOutputStream的方法
代码演示(将内存中的数据写出到文件中):
package com.lbj.javase.io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamTest06 {public static void main(String[] args) {FileOutputStream f=null;try {//321.txt 文件不存在的时候会自动新建一个新的文件//但是这种方式请谨慎使用,会使得原文件 !清空! 然后重写写入//f=new FileOutputStream("D:\\2021-2022课件\\321.txt");//以追加的方式在文件末尾写入,不会清空原文件内容f=new FileOutputStream("D:\\2021-2022课件\\321.txt",true);//开始写一个byte[]数组byte[] bytes={97,98,99};//将byte[] 数组全部写入321.txt中f.write(bytes);//将byte[] 的一部分写出f.write(bytes,0,2);String s="我是一个中国人";//将字符串变成字符byte[] b=s.getBytes();//写入321.txt中f.write(b);//写完之后,最后一定要刷新f.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}}
}
7、文件复制/拷贝
代码演示:
package com.lbj.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class CopyTest01 {public static void main(String[] args) {FileInputStream fis=null;FileOutputStream fos=null;try {//创建一个输入流对象fis=new FileInputStream("D:\\2021-2022课件\\123.txt");//创建一个输出流对象fos=new FileOutputStream("D:\\2021-2022课件\\321.txt");//核心:一边读,一边写byte[] bytes=new byte[1024*1024];//一次最多拷贝1MB//int readCount=0;while ((readCount=fis.read(bytes))!=-1){fos.write(bytes,0,readCount);}//刷新,输出流最后要刷新fos.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fos!=null){//分开try,不要一起try//一起try的时候,其中一个出现异常,可能会影响到另一个流的关闭try {fos.close();} catch (IOException e) {e.printStackTrace();}try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}
8、FileReader的使用
FileReader是文件字符输入流,负责读操作,文件只读取字符,且只能读取普通文本文件
代码演示:
package com.lbj.javase.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class FileReaderTest01 {public static void main(String[] args) {FileReader f=null;try {//创建文件输入流//123.txt里的字符为abcdeff=new FileReader("D:\\2021-2022课件\\123.txt");//开始读,一次只读2个字符char[] chars=new char[2];//往char数组中读
// int readCount=0;
// while((readCount=f.read(chars))!=-1){
// System.out.println(new String(chars,0,readCount));//ab cd ef
// }//同上,一次只读一个字符f.read(chars);for (char c:chars) {System.out.println(c);//a b}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}}
}
9、FileWriter的使用
FileWriter是文件字符输出流,负责写操作,文件只输出字符,且只能输出普通文本文件
代码演示:
package com.lbj.javase.io;import java.io.FileWriter;
import java.io.IOException;public class FileWriterTest01 {public static void main(String[] args) {FileWriter f=null;try {//创建文件输出流对象//123.txt的内容为abcdef//加了true这个参数后就不会清空f=new FileWriter("D:\\2021-2022课件\\123.txt",true);//开始写char[] chars={'g','h','i'};//没加append:true参数前,会对文件进行清空f.write(chars);//先清空,然后写出ghif.write("ccc");//不清空,然后写出ghiccc//刷新f.flush();} catch (IOException e) {e.printStackTrace();} finally {if(f!=null){try {f.close();} catch (IOException e) {e.printStackTrace();}}}}
}
10、复制普通文本文件
代码演示(字符文本之间的复制):
package com.lbj.javase.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class CopyTest02 {public static void main(String[] args) {FileReader fr=null;FileWriter fw=null;try {//创建读对象//abcdeffr=new FileReader("D:\\2021-2022课件\\123.txt");//创建写对象//aaafw=new FileWriter("D:\\2021-2022课件\\321.txt",true);//一边读一边写char[] chars=new char[1024*512];//1MBint readCount=0;while ((readCount= fr.read(chars))!=-1){fw.write(chars,0,readCount);}//结果:aaaabcdef//刷新fw.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {//分别抛异常if(fr!=null){try {fr.close();} catch (IOException e) {e.printStackTrace();}}if(fw!=null){try {fw.close();} catch (IOException e) {e.printStackTrace();}}}}
}
11、BufferedReader带有缓冲区的字符输入流
使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组,自带缓冲
当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流像当前这个程序来说:FileReader就是一个节点流,BufferedReader就是一个包装流
关闭流的时候只需要关闭最外层就行(查看源码得知)
代码演示:
package com.lbj.javase.io;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class BufferedReaderTest01 {public static void main(String[] args) throws Exception {//内容为:abcdef//// cccFileReader fi=new FileReader("D:\\2021-2022课件\\123.txt");//当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流//外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流//像当前这个程序来说:FileReader就是一个节点流,BufferedReader就是一个包装流BufferedReader br=new BufferedReader(fi);
/*//读第一行String firstLine=br.readLine();System.out.println(firstLine);//abcdef//读第二行String secondLine=br.readLine();System.out.println(secondLine);//空的一行,不返回任何值//读第三行String thirdLine=br.readLine();System.out.println(thirdLine);//ccc//读第四行String fourLine=br.readLine();System.out.println(fourLine);//如果是最后一行,返回null*///因此可以用循环,br.readLine()方法读取一个文本行,但不带换行符String s=null;while ((s=br.readLine())!=null){System.out.print(s);}//结果://abcdefccc//关闭流//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭br.close();}
}
12、节点流和包装流
节点流和包装流是相对而言的,在不同的位置,节点流和包装流会发生变化
代码演示:
package com.lbj.javase.io;import java.io.*;public class BufferReaderTest02 {public static void main(String[] args) throws Exception{//FileInputStream属于字节流FileInputStream fis=new FileInputStream("D:\\2021-2022课件\\123.txt");//InputStreamReader属于包装流//在这里fis是节点流,isr是包装流//通过转换流转换,将字节流转换成字符流InputStreamReader isr=new InputStreamReader(fis);//这个构造方法只能传递一个字符流,不能传递字节流//解决:使用转换流//在这里isr是节点流,br是包装流BufferedReader br=new BufferedReader(isr);//循环String line=null;while ((line=br.readLine())!=null){System.out.println(line);}//关闭最外层br.close();}
}
13、带有缓冲区的字符输出流
代码演示:
package com.lbj.javase.io;import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;public class BufferedWriterTest {public static void main(String[] args) throws Exception{//创建一个字节输出流FileOutputStream fos=new FileOutputStream("D:\\2021-2022课件\\123.txt",true);//创建一个转换流OutputStreamWriter osw=new OutputStreamWriter(fos);//带缓冲区的字符输出流BufferedWriter bw=new BufferedWriter(osw);//开始写,如果不在字节输出流的位置添加true,写的时候会把之前的内容清空bw.write("ddd");bw.write("eee");//刷新bw.flush();//关闭最外层bw.close();}
}
14、DataOutputStream和DataInputStream数据流
java.io.DataOutputStream :数据专属的流
作用:可以将数据连同数据类型一并写入文件
注意:这个文件不是普通文本文档(换句话来说就是这个文件用记事本编辑器打不开)
代码演示:
package com.lbj.javase.io;import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;public class DataOutputStreamTest01 {public static void main(String[] args) throws Exception {//创建字节输出流FileOutputStream fos=new FileOutputStream("D:\\2021-2022课件\\321",true);//创建数据专属的字节输出流DataOutputStream dos=new DataOutputStream(fos);//写数据byte b=100;short s=200;boolean x=true;//写//把数据以及数据的类型一并写入到文件中,相当于加密,并且严格规定顺序dos.writeByte(b);dos.writeShort(s);dos.writeBoolean(x);//刷新dos.flush();//关闭最外层dos.close();}
}
DataInputStream :数据字节输入流
DataOutputStream :写的文件,只能使用DataInputStream去读,并且读的时候需要提前知道写入的顺序,读的顺序要和写的顺序一致,才可以正常取出数据
代码演示:
package com.lbj.javase.io;import java.io.DataInputStream;
import java.io.FileInputStream;public class DataInputStreamTest01 {public static void main(String[] args) throws Exception{//创建字节输入流FileInputStream fi=new FileInputStream("D:\\2021-2022课件\\321");//创建数据字节输入流DataInputStream dis=new DataInputStream(fi);//开始读Byte b=dis.readByte();Short s=dis.readShort();Boolean x=dis.readBoolean();System.out.println(b);System.out.println(s);System.out.println(x);//关闭流dis.close();}
}
15、PrintStream标准输出流
java.io.PrintStream:标准的字节输出流,默认输出到控制台,还可以改变输出方向
代码演示:
package com.lbj.javase.io;import java.io.FileOutputStream;
import java.io.PrintStream;public class PrintStreamTest01 {public static void main(String[] args) throws Exception{//联合起来System.out.println("helloworld");//拆分开//System.out返回值类型是PrintStreamPrintStream ps=System.out;ps.println("hello");ps.println("world");//标准输出流不需要手动close()关闭//可以改变标准输出流的输出方向吗?可以//标准输出流不再指向控制台,指向123.txt文件FileOutputStream fos=new FileOutputStream("D:\\2021-2022课件\\123.txt");PrintStream ps2=new PrintStream(fos);//修改输出方向,将输出方向修改到123.txt文件System.setOut(ps2);//再输出System.out.println("hello");System.out.println("world");
//打印到123.txt文件中了}
}
日志工具:
可以用来打印日志,以后开发必不可少
代码演示(自定义一个日志工具类):
package com.lbj.javase.io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;/*** 自定义日志工具类*/
public class Logger {public static void log(String msg){try {//创建字节输出流,指向一个日志文件FileOutputStream fos=new FileOutputStream("log.txt",true);//创建标准输出流PrintStream out=new PrintStream(fos);//改变输出位置System.setOut(out);//获取当前时间Date nowTime=new Date();//规定时间格式SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");//转换格式String s=sdf.format(nowTime);//输出到log.txt文件中System.out.println(s+":"+msg);} catch (FileNotFoundException e) {e.printStackTrace();}}
}
测试类:
package com.lbj.javase.io;public class LoggerTest {public static void main(String[] args) {Logger.log("用户正在进行登录,验证失败");Logger.log("这是日志记录工具噢");}
}
测试结果:
2021-04-22 21:36:15 340:用户正在进行登录,验证失败
2021-04-22 21:36:15 372:这是日志记录工具噢
16、File类
File有可能是目录,也有可能是文件,或者是路径名
1、File类和四大家族没有关系(看继承结构得知),所以File类不能完成文件的“读”和“写”
2、File只是一个路径名的抽象表示形式
代码演示(File类中常用的方法):
package com.lbj.javase.io;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @author LBJ* @version V1.0* @Package com.lbj.javase.io* @date 2021/4/25 23:21* @Copyright 公司*/
public class FileTest01 {public static void main(String[] args) throws IOException {//这个路径下是没有file文件File f=new File("D:\\2021-2022课件\\file");//判断是否存在file文件System.out.println(f.exists());//false// //判断是否存在file文件,如果没有此文件,则在此路径下创建file文件
// if(!f.exists()){
// f.createNewFile();
// }//判断是否存在file文件夹,如果没有此文件夹,则在此路径下创建file文件夹
// if(!f.exists()){
// f.mkdir();
// }//判断是否存在file"多重文件夹",如果没有,则创建,注意是mkdirs()不是mkdir()
// File f2=new File("D:\\2021-2022课件\\file\\a\\b\\c");
// if(!f2.exists()){
// f2.mkdirs();
// }//获取文件的父路径File f3=new File("D:\\2021-2022课件\\123.txt");String parent=f3.getParent();System.out.println(parent);//D:\2021-2022课件//另一种形式,以File类型的形式File paren1=f3.getParentFile();System.out.println(paren1);//D:\2021-2022课件//获取文件的绝对路径File parent3=f3.getAbsoluteFile();System.out.println(parent3);//D:\2021-2022课件\123.txt//获取文件名System.out.println(f3.getName());//判断是否是一个目录System.out.println(f3.isDirectory());//判断是否是一个文件System.out.println(f3.isFile());//获取文件最后一次修改时间(返回值是毫秒)long haoMiao=f3.lastModified();System.out.println(haoMiao);//1619097200422//将总毫秒数转换成 日期Date time=new Date(haoMiao);SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");String strTime=sdf.format(time);System.out.println(strTime);//2021-04-22 21:13:20 422//获取文件大小System.out.println(f3.length());//14字节//File中的listFiles方法,可以获取当前目录下的所有子文件,返回的是FIle类型的数组File[] files=f.listFiles();//foreachfor (File file:files) {//获取当前目录下的所有子的绝对路径System.out.println(file.getAbsoluteFile());//D:\2021-2022课件\file\a//获取当前目录下的所以子目录名字System.out.println(file.getName());//a}}
}
17、练习目录拷贝
代码演示():
package com.lbj.javase.io.ioTest01;import java.io.*;public class CopyAll {public static void main(String[] args) {//拷贝源File srcFile=new File("拷贝源路径");//拷贝目标File destFile=new File("拷贝目标路径");//调用方法拷贝copyDir(srcFile,destFile);}/*** 拷贝目录方法* @param srcFile 拷贝源* @param destFile 拷贝目标*/private static void copyDir(File srcFile,File destFile){if(srcFile.isFile()){//srcFile如果是一个文件的话,递归结束//判断是文件的时候 需要拷贝FileInputStream in=null;FileOutputStream out=null;try {in=new FileInputStream(srcFile);//拼接新的一个路径,涉及大量的字符串 拼接 操作 String path=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath(): destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3);out=new FileOutputStream(path);//一边读一边写byte[] bytes=new byte[1024*1024];int readCount=0;while((readCount=in.read(bytes))!=-1){out.write(bytes,0,readCount);}out.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(in!=null){try {in.close();} catch (IOException e) {e.printStackTrace();}}if(out!=null){try {out.close();} catch (IOException e) {e.printStackTrace();}}}return;}//将拷贝源的子目录存放到File[]数组中File[] files=srcFile.listFiles();for (File f:files) {//测试:获取所有文件的绝对路径//System.out.println(f.getAbsoluteFile());if(f.isDirectory()){//源目录路径String srcDir=f.getAbsolutePath();//关键在于目标目录的路径String destDir=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath(): destFile.getAbsolutePath()+"\\")+srcDir.substring(3);//以多重目录的形式建目录File newFile=new File(destDir);if(!newFile.exists()){newFile.mkdirs();}}//递归调用copyDir(f,destFile);}}
}