目录
1. FileInputStream下的读文件方法:read()
1.2 在外面创建InputStream对象, 再使用finally释放的方法太麻烦。可以写在try()内, 就可以自动释放。化简如下:
1.3 read(byte[] b, int off, int len)读取文件
1.4 在InputStream中,由于都是以字节为单位进行操作的,所以文件中的中文会乱码,那么我们可以这样读取中文文档:
1.5 上述我们以3位合成一位读取中文,也不是一定能读取成功的。读取中文文档我们通常使用的是Scanner方法:
2. FileOutputStream下的写文件方法:write()
2.3 write(byte[] b, int off, int len)
2.4 outputStream加PrintWriter 追加在文档后边
3. Reader---读操作(操作的对象以char位单位,是文本)
4. Writer---写操作(操作对象是文本)(覆盖操作)
1.扫描指定目录,并找到名称或者内容中包含指定 字符的所有普通文件(不包含目录)
3.扫描指定目录(当前目录以及子目录),并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件
文件基本操作-查看文件名,路径名
1.绝对路径和相对路径相关概念
从根节点开始,到达目标文件的路径的描述
项目中,使用的大多都是相对路径
1.1 绝对路径
1.2相对路径(基准路径)
2.文件的三种构造方法
构造函数 里边的路径可以相对路径也可以写绝对路径
2.1 构造方法
File(String pathname) | 根据文件路径创建一个新的File实例 |
File(String parent,String child) | 根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示 (前边是父目录,后边为名称) |
File(File parent,String child) | 根据父目录+孩子文件路径,创建一个新的File实例 |
2.2 代码实现:
//构造函数 : 里边的路径可以相对路径也可以写绝对路径
//路径分隔用 / 或者 \\ 都可以
//根据文件路径创建一个新的File实例
File file=new File("D:/temp/aaa.text");
//根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示
File file1=new File("D:/temp","aaa.txt");
//根据父目录+孩子文件路径,创建一个新的File实例
File file2=new File(new File("D:/temp"),"");
3.文件名称 文件路径等基本方法列表
3.1方法
getParent() | 获取文件的父目录 |
getName() | 获取文件名 |
getPath() | 获取文件路径(构造File)时候指定的路径 |
getAbsolutePath() | 获取绝对路径(简单拼装) |
getCanonicalPath() | 获取绝对路径 |
exists() | 是否存在 |
isDirectory() | 是否是目录 |
isFile() | 是否是文件 |
canRead() | 是否可读 |
canWrite() | 是否可写 |
createNewFile() | 创建文件 |
mkdir() / mkdirs() | 创建目录 / 一次创建多级目录 |
delete() | 删除文件 |
deleteOnExit | 退出时删除,更推荐,更安全 |
String[] list() | 显示路径目录下的所有文件和文件名,返回的是String数组 |
File[] listFiles() | 显示路径下的文件和目录的 绝对路径,返回的是File数组 |
f1.renameTo(f2) | 文件改名 |
3.2上述方法的代码应用
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) throws IOException {
//分隔符
//分隔多个路径 ;
System.out.println(File.pathSeparator);
//目录分隔符 \
System.out.println(File.separator);
//构造函数 : 里边的路径可以相对路径也可以写绝对路径
//路径分隔用 / 或者 \\ 都可以
//根据文件路径创建一个新的File实例
File file=new File("D:/temp/aaa.text");
//根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示
File file1=new File("D:/temp","aaa.txt");
//根据父目录+孩子文件路径,创建一个新的File实例
File file2=new File(new File("D:/temp"),"");
//获取父目录
System.out.println(file.getParent());
//获取文件名
System.out.println(file.getName());
//相对路径,当前目录下(当前代码的路径)的hello.txt
file=new File("./hello.txt");
//获取文件路径
System.out.println(file.getPath());
//获取绝对路径(简单拼装)
System.out.println(file.getAbsoluteFile());
//获取绝对路径
System.out.println(file.getCanonicalFile());
//其他操作
//文件是否存在
System.out.println(file.exists());
//是否是目录
System.out.println(file.isDirectory());
//是否是文件
System.out.println(file.isFile());
if(!file.exists()){
file.createNewFile();
}
if(!file1.exists()){
file1.createNewFile();
}
System.out.println("===================");
file2=new File("D:\\temp\\hello");
if(!file2.exists()){
file2.createNewFile();
}
if(file2.exists()){
//file2.delete();//直接删除
file2.deleteOnExit();//退出时候删除,更推荐
}
System.out.println("=======================");
File file3=new File("D:/temp");
//返回当前目录下的 目录和文件 名称,返回的是String数组
String[] files=file3.list();
Arrays.stream(files).forEach(System.out::println);
System.out.println("----");
//返回当前目录下 所有文件和目录的 绝对路径,返回的是File数组
File[] files3=file3.listFiles();
Arrays.stream(files3).forEach(x->System.out.println(x.getName()));
//一次创建多级目录就用mkdirs()
File file4=new File("D:/temp/a1/b1");
file4.mkdirs();
//查看是否有读写权限
System.out.println("=-=-=-=-=-=-=-=");
File file5=new File("D:/temp/asas.txt");
System.out.println(file5.canRead());
System.out.println(file5.canWrite());
//文件改名操作
File file6=new File("D:/temp/cat");
file6.renameTo(new File("D:/temp/catcat"));
}
}
文件读写操作
1.文件分类
1.1二进制文件
数据在内存中以二进制的形式存储的
1.2文本文件
也属于二进制文件,只是文件中相邻的字节组成了一个字符
2.文件读写的相关文件类
父类 | 子类 | |
字节流对象 (二进制) | InputStream | FileInputStream |
OutputStream | FileOutputStream | |
字符流对象 (文本) | Reader | FileReader |
Writer | FileWriter |
-
字节流对象操作的是字节,byte
-
字符流对象操作的是字符,char
FileInputStream | FileInputStream(File file) | 利用file构造文件输入流 |
FileInputStream(String name) | 利用文件路径构造文件输入流 | |
FileOutputStream | FileOutputStream(File file) | |
FileOutputStream(File file,boolean append) | 追加 | |
FileOutputStream(String name) | ||
FileOutputStream(String name, boolean append) | 追加 |
这里的name指的是文件的路径(相对/绝对)
3.文件读写的相关方法列表
a. 关闭和刷新
close()操作 | Void close() | 资源关闭 |
fiush()操作 | Void flush() | 刷新缓冲区 |
b. FileInputStream下的读文件方法:read()
read()操作 | Abstract int read() | 一次一个字节 |
Int read(byte[] b) | 一次多个字节 | |
Int read(byte[] b,int off,int len) | 一次多个字节 |
c. FileOutputStream下的写文件方法:write()
write()操作 | Abstract void write(int b) | 一个字节一个字节的写入文件 |
Void write(byte[] b) | 把byte数组内容,写入文件 | |
Void write(byte[] b, int off, int len) | 从byte[]数组内容的off下标开始写,写len长度 | |
PrintWriter |
4.代码实现
1. FileInputStream下的读文件方法:read()
import javax.management.RuntimeErrorException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
//文件读操作
//InputStream下的read()方法,针对二进制文件,每次byte为操作单位,中文乱码
public class Demo2 {
public static void main(String[] args) {
//read()方式读取数据,中文乱码
read1();
System.out.println("\n");
//read()方式读取数据,简化写法
read2();
System.out.println("\n");
//read(byte[] b, int off, int len)
read3();
System.out.println("\n");
//读取中文文档
read4();
//使用Scanner来读取文件->中文正常显示
read5();
}
}
1.1通过Abstract int read()方法读取
//通过read()方法读取数据
private static void read1(){
InputStream inputStream=null;
try{
inputStream=new FileInputStream("D:/temp/aaa.txt");
while(true){
int b=inputStream.read();
if(b==-1){
break;
}
System.out.print((char)b);
}
}catch(FileNotFoundException e){
throw new RuntimeException(e);
}catch(IOException e){
throw new RuntimeException(e);
}finally{
//必须在finally里边关闭文件
try{
inputStream.close();
}catch (IOException e){
throw new RuntimeException(e);
}
}
}
1.2 在外面创建InputStream对象, 再使用finally释放的方法太麻烦。可以写在try()内, 就可以自动释放。化简如下:
//简写
//在外面创建InputStream对象, 再使用finally释放的方法太麻烦.
//可以写在try()内, 就可以自动释放
private static void read2(){
try(InputStream inputStream=new FileInputStream("D:/temp/aaa.txt")){
while(true){
int b=inputStream.read();
if(b==-1){
break;
}
System.out.print((char)b);
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
1.3 read(byte[] b, int off, int len)读取文件
//read(byte[] b, int off, int len)
private static void read3(){
try(InputStream inputStream=new FileInputStream("D:/temp/aaa.txt")){
byte[] buf=new byte[1024];//这个数字是随便写的,只是一个象征值
while(true){
// 返回的是字符的长度,用int 接收
int num=inputStream.read(buf);
if(num==-1){
break;
}
for(int i=0;i<num;i++){
System.out.print((char)buf[i]);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
1.4 在InputStream中,由于都是以字节为单位进行操作的,所以文件中的中文会乱码,那么我们可以这样读取中文文档:
//读取中文文档方式
private static void read4() {
try(InputStream inputStream=new FileInputStream("D:/temp/aaa.txt")){
byte[] buf=new byte[1024];
while(true){
int num=inputStream.read(buf);
if(num==1){
break;
}
for(int i=0;i<num;i++){
System.out.print(new String(buf,i,3));
}
}
}catch(Exception e){
e.printStackTrace();
}
}
1.5 上述我们以3位合成一位读取中文,也不是一定能读取成功的。读取中文文档我们通常使用的是Scanner方法:
//Scanner的方式读取文件
private static void read5() {
try(InputStream inputStream=new FileInputStream("D:/temp/aaa.txt")){
Scanner scanner=new Scanner(inputStream);
while(scanner.hasNext()){
String str=scanner.nextLine();
System.out.println(str);
}
}catch(Exception e){
e.printStackTrace();
}
}
2. FileOutputStream下的写文件方法:write()
flush()可以不写,但是写了就写入的足够及时,加了才能保证写入成功
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
//文件写操作
//OutputStream下的write()方法
public class Demo3 {
public static void main(String[] args) {
//write(int b)
write1();
//write(byte[] b)
write2();
//write(byte[] b, int off, int len)
write3();
//outputStream加PrintWriter 追加在文档后边
write4();
//直接PrintWriter,覆盖
write5();
}
}
2.1 write(int b)
private static void write1() {
try(OutputStream outputStream=new FileOutputStream("D:/temp/asas.txt")){
outputStream.write('h');
outputStream.write('e');
outputStream.write('l');
outputStream.write('l');
outputStream.write('o');
outputStream.flush();//可以不写,但是写了就写入的足够及时
}catch(Exception e){
e.printStackTrace();
}
}
2.2 write(byte[] b)
private static void write2() {
try(OutputStream outputStream=new FileOutputStream("D:/temp/asas.txt")){
outputStream.write("hello2222".getBytes());
outputStream.flush();
}catch(Exception e){
e.printStackTrace();
}
}
2.3 write(byte[] b, int off, int len)
private static void write3() {
try(OutputStream outputStream=new FileOutputStream("D:/temp/asas.txt")){
outputStream.write("hello22233".getBytes(),3,2);
outputStream.flush();
}catch(Exception e){
e.printStackTrace();
}
}
2.4 outputStream加PrintWriter 追加在文档后边
private static void write4() {
try(OutputStream outputStream=new FileOutputStream("D:/temp/asas.txt",true)){
try(PrintWriter writer=new PrintWriter(outputStream)){
writer.println("你好");
writer.println("java");
outputStream.flush();
}
}catch(Exception e){
e.printStackTrace();
}
}
2.5 直接PrintWriter,覆盖
private static void write5() {
try{
PrintWriter writer=new PrintWriter("D:/temp/asas.txt");
writer.println("你好!!!");
writer.println("java!!!!!!");
writer.flush();
}catch(Exception e){
e.printStackTrace();
}
}
3. Reader---读操作(操作的对象以char位单位,是文本)
import java.io.FileReader;
import java.io.Reader;
//Reader读操作
public class ReaderDemo {
public static void main(String[] args) {
try(Reader reader=new FileReader("D:/temp/aaa.txt")){
char[] buf=new char[1024];
while(true){
int num=reader.read(buf);
if(num==-1){
break;
}
for(int i=0;i<num;i++){
System.out.println(buf[i]);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
4. Writer---写操作(操作对象是文本)(覆盖操作)
import java.io.FileWriter;
import java.io.Writer;
//Writer 写操作(覆盖原来的内容)
//每个写操作后边都要记得调用flush()方法
public class WriterDemo {
public static void main(String[] args) {
try(Writer writer=new FileWriter("D:/temp/aaa.txt")){
writer.write("nihao,爱你哦");
writer.write("sjojo");
writer.flush();
}catch(Exception e){
e.printStackTrace();
}
}
}
几个使用实例
1.扫描指定目录,并找到名称或者内容中包含指定 字符的所有普通文件(不包含目录)
注意:我们现在的方案性能较差,所以尽量不要在太复杂的目录下或者大文件下实验
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.Scanner;
public class FileMatchDemo {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要查找的目录:");//路径
String rootPath=scanner.nextLine();
System.out.println("请输入要查找的内容字符串:");
String key=scanner.nextLine();
//根据路径,创建一个新的File实例
File rootFile=new File(rootPath);//里边放的是要查找的指定目录
//输入的目录不存在,或者此路径不是目录,则直接返回
if(!rootFile.exists() || !rootFile.isDirectory()){
return;
}
//查找逻辑
searchDir(rootFile,key);
}
//在指定目录下,查找指定内容的文件,并判断其是不是目录
private static void searchDir(File rootFile, String key) {
//返回的是 路径下所有 文件和目录的 绝对路径
File[] files=rootFile.listFiles();
for(File f:files){
//如果是目录,递归,直到它不是目录
if(f.isDirectory()){
searchDir(f,key);
}else{
//判断是否包含指定字符串
if(matchKey(f,key)){
//获取文件路径(构造的时候指定的路径)
System.out.println(f.getPath());
}
}
}
}
//判断文件中的内容是否包含指定字符串
//传入文件和要查找的内容
//根据传过来的路径读取文件,创建新的可变字符串,将读取的内容写进字符串,
//返回的时候返回字符串中是否包含 要查找的内容
private static boolean matchKey(File f, String key) {
StringBuilder builder=new StringBuilder();
try(Reader reader=new FileReader(f)){
char[] buf=new char[1024];//这个数字随便写的
while(true){
int len=reader.read(buf);
if(len == -1){
break;
}
builder.append(buf,0,len);
}
}catch(Exception e){
e.printStackTrace();
}
return builder.toString().contains(key);
}
}
2.文件的复制
import java.io.*;
import java.util.Scanner;
public class FileCopy {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入源文件:");
String input=scanner.nextLine();
System.out.println("请输入目标文件:");
String output=scanner.nextLine();
//创建一个输入文件
File inputFile=new File(input);
if(!inputFile.exists()||!inputFile.isFile()){
return;
}
//创建一个输出文件
File outputFile=new File(output);
copy(inputFile,outputFile);
}
private static void copy(File inputFile, File outputFile) {
//先读再写
try(InputStream inputStream=new FileInputStream(inputFile)){
try(OutputStream outputStream=new FileOutputStream(outputFile)){
byte[] buf=new byte[1024];
while(true){
int len=inputStream.read(buf);
if(len==-1){
break;
}
//文件的写入
outputStream.write(buf,0,len);
//不要忘了flush()
outputStream.flush();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
结果显示:
3.扫描指定目录(当前目录以及子目录),并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class FileScan {
static Scanner scanner = new Scanner(System.in);
//输入要查找的目录
public static void main(String[] args) {
System.out.println("请输入要查找的目录:");
String path = scanner.nextLine();
System.out.println("请输入要查找的文件:");
String searchFile = scanner.nextLine();
File filePath = new File(path);
if (!filePath.exists() || !filePath.isDirectory()) {
System.out.println("目录不存在");
return;
}
//扫描
//List存储扫描出的文件
List<File> toScanFile = new ArrayList<>();
scan(filePath, searchFile, toScanFile);
//询问是否删除
isDelete(toScanFile);
}
private static void isDelete(List<File> toScanFile) {
if(toScanFile.size()==0){
return;
}
//遍历链表
for(File f:toScanFile){
System.out.println("是否删除文件:(y代表删除)"+f.getAbsoluteFile());
//获取用户的输入情况
String isis=scanner.nextLine();
if("y".equals(isis)){
f.delete();
}
}
}
private static void scan(File filePath, String searchFile, List<File> toScanFile) {
File[] files = filePath.listFiles();//返回的是当前路径下的所有文件和目录的绝对路径
if (files == null || files.length == 0) {
return;
}
for (File f : files) {
if (f.isDirectory()) {
scan(f, searchFile, toScanFile);
} else {
//文件名字和查找的字符相等 就放进存储的链表中
if (f.getName().equals(searchFile)) {
toScanFile.add(f);
}
}
}
}
}
结果显示:
文件操作相关知识总结,希望写的足以明了~