文件操作(java)
1.java中操作文件
1.1File类
java中用File类来描述文件,由于每个操作系统的文件形式都不一样,JVM为程序员统一了对各个操作系统中文件的操作。
1.1.1属性
首先介绍一下其中File类中常见的属性:
这两个属性分别代表的是操作系统中的目录分隔符、路径分隔符
在Windows系统下将属性打印对应得到
1.1.2构造方法
我们主要学习后三个构造方法
构造方法 | 解释 |
public File(String pathname) | 根据路径创建,相对路径,绝对路径都可以 |
public File(File parent, String child) | 根据父目录+孩子文件路径创建 |
public File(String parent, String child) | 根据父目录路径和孩子文件路径创建 |
public class Demo_0302 {public static void main(String[] args) {//根据路径直接创建File file = new File("d:/temp/text.txt");System.out.println(file);//创建一个父目录,父目录加孩子路劲File file1 = new File("d:/temp");File file2 = new File(file1,"/text.txt");System.out.println(file1);System.out.println(file2);//根据父目录、孩子路径File file3 = new File("d:/temp","/exam");System.out.println(file3);}
}
1.1.3常用方法
访问文件的一些属性
public class Demo_0303 {public static void main(String[] args) throws IOException {File file = new File("d:/temp/text.txt");System.out.println(file.getParent());//返回文件的父目录System.out.println(file.getName());//返回文件的名字System.out.println(file.getPath());//返回文件路径System.out.println(file.getAbsolutePath());//返回文件绝对路径System.out.println(file.getCanonicalPath());//返回文件修饰过的绝对路径}
}
创建文件以及验证文件是目录还是文件
public class Demo_0304 {public static void main(String[] args) throws IOException {File file = new File("d:/temp/text.txt");System.out.println("文件是否存在"+file.exists());//文件是否真实存在//根据 File 对象,⾃动创建⼀个空⽂件。成功创建后返回 trueSystem.out.println("文件是否创建成功"+file.createNewFile());System.out.println("文件是否存在"+file.exists());//文件是否真实存在System.out.println("该文件对象代表是否是目录"+file.isDirectory());//判断对象是否是目录System.out.println("该文件对象代表是否是文件"+file.isFile());System.out.println("文件是否删除"+file.delete());System.out.println("文件是否存在"+file.exists());}
}
创建目录
public class Demo_0305 {public static void main(String[] args) {File file1 = new File("d:/temp/xxx");//创建temp目录下的一个子目录System.out.println(file1.mkdir());//创建temp目录下的两个连续子目录,使用mkdir会失败File file = new File("d:/temp/aaa/bbb");System.out.println(file.mkdir());//在父目录不存在时,需要使用mkdirsSystem.out.println(file.mkdirs());}
}
文件修改重命名
public class Demo_0306 {public static void main(String[] args) throws IOException {File file = new File("d:/temp/text.txt");File dest = new File("d:/temp/t.txt");System.out.println(file.exists());System.out.println(dest.exists());System.out.println(file.getName());file.renameTo(dest);System.out.println(file.exists());System.out.println(dest.exists());System.out.println(file.getName());System.out.println(dest.getName());}
}
2.数据流(文件读写到内存)
我们以主存为中心,将数据与主存交换通过一种数据流的方式,在Java中利用两个抽象类来描述。
2.1InputStream
InputStream主要实现以下方法
返回值 | 方法名 | 说明 |
int | read() | 读取一个字节数据,直到读取到-1,读取结束 |
int | read(byte[] b) | 一次最多读取b数组长度的字节,并存到b中,返回实际读到的数量,如果返回-1,代表读完 |
int | read(byte[] b,int off,int len) | 每次最多读取len长度的字节数据,从b中off位置开始存储,返回读取到的数量,返回-1读取结束 |
void | close() | 关闭流 |
2.1.1FileInputStream

该类主要用于文件的读取操作,以字节流读取。
构造方法:
1.参数为文件路径
2.参数为文件对象
主要方法也就是继承抽象类重写的上述介绍的读操作以及关闭流。
public class Demo_0401 {public static void main(String[] args) throws IOException {File file = new File("d:/temp/text.txt");//用于读二进制文件,以字节流读取InputStream inputStream = new FileInputStream(file);//每次读取一个字节while(true){int data = inputStream.read();if(data==-1){break;}System.out.println(data);}//关闭流,由于每次打开一个流,对应文件描述表中会添加一个文件描述符表示需要使用到的文件//需用完后即使删除,否则可能会溢出inputStream.close();}
}
public class Demo_0401 {public static void main(String[] args) throws IOException {File file = new File("d:/temp/text.txt");//用于读二进制文件,以字节流读取InputStream inputStream = new FileInputStream(file);//每次读取用数组接受while (true) {byte[] bytes = new byte[1024];int len = inputStream.read(bytes);if(len==-1){break;}for (int i = 0; i < len; i++) {System.out.println(bytes[i]);}}//关闭流inputStream.close();}
}
可见使用FileInputStream是十分麻烦的,所以我们可以使用Scanner类来读取文件内容。
public class Demo_0403 {public static void main(String[] args) throws FileNotFoundException {InputStream fileInputStream = new FileInputStream("d:/temp/text.txt");Scanner scanner = new Scanner(fileInputStream);while(scanner.hasNextLine()){System.out.println(scanner.nextLine());}try {fileInputStream.close();} catch (IOException e) {throw new RuntimeException(e);}}
}
2.2OutputStream
输出流与输入流类似,但是输出流在工作时,会将主存中的内容先写到缓冲区内,等到所有写操作完成时,再全部将缓冲区的内容写到磁盘中,如果程序中间出现异常中断,逻辑会出现问题,所以在每次写时我们会进行一次刷新操作,把缓冲区的内容写到磁盘内。
返回值 | 方法名 | 说明 |
void | write(int b) | 写入要给的数据b |
void | write(byte b[]) | 写入数组中的内容 |
int | write(byte[] b,int off,int len) | 将b中从off开始的内容写入,一共len个长度 |
void | close() | 关闭流 |
void | flush() | 刷新操作,将缓冲区的内容写入到磁盘 |
2.2.1FileOutputStream
public class Demo_0404 {public static void main(String[] args) throws IOException {OutputStream fileOutputStream = new FileOutputStream("d:/temp/writer.txt");byte[] bytes ={97,98,99,'a','b','\n'};fileOutputStream.write(bytes);fileOutputStream.flush();fileOutputStream.close();}
}
写操作利用FileOutputStream十分不方便,我们可以利用PrintWriter类来完成输出。
public class Demo_0404 {public static void main(String[] args) throws IOException {OutputStream fileOutputStream = new FileOutputStream("d:/temp/writer.txt");PrintWriter printWriter = new PrintWriter(fileOutputStream);printWriter.write("你好呀");printWriter.write("\n");printWriter.write("hello world!!!");printWriter.flush();fileOutputStream.close();}
}
3.小练习
1.扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否要删除该⽂件
public class Demo_0405 {public static void main(String[] args) {//1.获取用户输入需要扫描的目录Scanner scanner = new Scanner(System.in);System.out.println("请输入扫描的目录:");String rootFile = scanner.next();File file = new File(rootFile);//2。找到该目录//如果目录不存在if(!file.exists()){System.out.println("目录不存在");return;}//如果不是目录if(!file.isDirectory()){System.out.println("你输入的文件地址不是目录");return;}//3。获取用户需要指定指定的字符System.out.println("请输入需要指定文件名包含的字符串");String name = scanner.next();if(name==null||name.isEmpty()){System.out.println("输入的字符串为空");}//4。获取该目录下的所有文件scan(file,name);}private static void scan(File rootFile, String name) {//获取该目录下的所有文件File[] files = rootFile.listFiles();//如果该目录中文件为空返回if(files.length==0) {return;}//处理该目录下的文件for(File file:files){//5.如果是目录,递归第4步if(file.isDirectory()){scan(file,name);}else{//6.如果是文件检查是否包含字符,是则询问用户是否删除if(file.getName().contains(name)){System.out.println("找到了指定文件,是否删除:yes/no");Scanner scanner = new Scanner(System.in);String next = scanner.next();if(next.equals("yes")){//删除file.delete();if(!file.exists()) {System.out.println("删除成功");}else{System.out.println("删除失败");}}}}}}
}
2.复制文件,将用户指定源文件内容复制到指定文件中
public class Demo_0406 {public static void main(String[] args) {//进⾏普通⽂件的复制,用户输入一个指定源文件,并将文件内容复制到用户指定的一个新文件//1.接受用户输入的源文件,并校验是否有效System.out.println("请输入源文件路径");Scanner scanner = new Scanner(System.in);String soursePath = scanner.next();//校验文件是否存在File sourseFile = new File(soursePath);if (!sourseFile.exists()) {System.out.println("文件不存在");return;}if (!sourseFile.isFile()) {System.out.println("文件是目录");return;}//2.接收用户输入的目标文件,并校验是否有效//如果目标文件已存在或者给的目标文件路径没有父目录都不合法//接收目标文件路径System.out.println("请输入目标文件路径");String destPath = scanner.next();File destFile = new File(destPath);//如果目标文件已存在if (destFile.exists()) {System.out.println("目标文件已存在");return;}//如果目标文件的父目录不存在if (!destFile.getParentFile().exists()) {System.out.println("目标文件父目录不存在");return;}//3.进行文件复制阶段//读取,创建输入输出流try(InputStream fileInputStream = new FileInputStream(sourseFile);OutputStream fileOutputStream = new FileOutputStream(destFile)) {//指定一次读1KBbyte[] bytes = new byte[1024];while (true) {int len = fileInputStream.read(bytes);if(len == -1){break;}fileOutputStream.write(bytes,0,len);}fileOutputStream.flush();System.out.println("复制成功");} catch (IOException e) {throw new RuntimeException(e);}}
}
3.扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)
public class Demo_0407 {public static void main(String[] args) {//扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)//1.获取用户输入需要扫描的目录Scanner scanner = new Scanner(System.in);System.out.println("请输入扫描的目录:");String rootPath = scanner.next();File rootFile = new File(rootPath);//2。找到该目录//如果目录不存在if(!rootFile.exists()){System.out.println("目录不存在");return;}//如果不是目录if(!rootFile.isDirectory()){System.out.println("你输入的文件地址不是目录");return;}//3。获取用户需要指定指定的字符System.out.println("请输入需要指定文件包含的字符串");String keyWord = scanner.next();if(keyWord==null||keyWord.isEmpty()){System.out.println("输入的字符串为空");}//4。获取该目录下的所有文件scan(rootFile,keyWord);}private static void scan(File rootFile, String keyWord) {//获取该目录下的所有文件File[] files = rootFile.listFiles();if(files.length==0)return;//如果该目录中文件为空返回//处理该目录下的文件for(File file:files){//5.如果是目录,递归第4步if(file.isDirectory()){scan(file,keyWord);}else {boolean isDestFile = checkFile(file, keyWord);if (!isDestFile) {continue;} else {isDelete(file);}}}}private static boolean checkFile(File file, String keyWord) {//检查文件名是否包含if (file.getName().contains(keyWord)) {return true;}//检查文件内容是否包含关键字//读取文件内容StringBuilder stringBuilder = new StringBuilder();try (FileInputStream fileInputStream = new FileInputStream(file)) {while (true) {Scanner scanner = new Scanner(fileInputStream);if(!scanner.hasNextLine()){break;}stringBuilder.append(scanner.nextLine());}} catch (IOException e) {throw new RuntimeException(e);}if(stringBuilder.toString().contains(keyWord)){return true;}return false;}private static void isDelete(File file) {System.out.println("已找到包含关键字的文件"+file.getPath()+"是否删除:Y/N");Scanner scanner = new Scanner(System.in);String string = scanner.next();if(string.toLowerCase().equals("y")){file.delete();if (!file.exists()) {System.out.println("删除成功");}else{System.out.println("删除失败");}}}
}