在计算机中,大前提下,所有的文件都是二进制的,有些文本文件比较特殊,二进制数据刚好可以构成字符
Java标准库中提供了一系列类用来操作文件

File类
File用于操作系统文件,可以抽象表示为文件或者目录,但它根本上不是,只是代表文件或者目录的路径
File中的常用方法
public class Demo1 {
public static void main(String[] args) throws IOException {
// File file=new File("E:/编程的学习/Java EE初阶/newFile/newFile/test.txt");
File file=new File("./test.txt");
System.out.println(file.getParent());//返回file对象的父目录文件路径
System.out.println(file.getName());//返回file对象的文件名称
System.out.println(file.getPath());//返回file对象的文件路径
System.out.println(file.getAbsolutePath());//返回file对象的绝对路径
System.out.println(file.getCanonicalPath());//返回file对象的修饰过的绝对路径
System.out.println(file.exists());//返回file对象描述的文件是否真实存在
}
}

![]()
public class Demo2 {
public static void main(String[] args) throws IOException {
File file=new File("./test.txt");
System.out.println(file.createNewFile());//如果该文件不存在,则可以直接创建
System.out.println(file.getAbsolutePath());//得到文件的绝对路径
System.out.println(file.getName());//得到文件的名称
System.out.println(file.getPath());//得到文件的路径
}
}

文件操作常常涉及到的异常

file.delete()立刻删除该文件
file.deleteOnExit()删除文件动作到jvm运行结束后才会进行
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
File file=new File("./test.txt");
file.delete();//立刻删除该文件
file.deleteOnExit();//根据file对象,标注该文件将会被删除,删除动作到jvm运行结束后才会进行
Thread.sleep(10000);
}
}
file.list();获得该目录下的所有目录或者文件名
file.listFiles()获得该目录下的所有目录或者文件名的绝对路径
public class Demo4 {
public static void main(String[] args) {
// 针对list的操作只能根据目录来完成,不能根据单个文件
File file=new File("E:/");
String[] s=file.list(); //返回File对象代表的目录下的文件名
System.out.println(Arrays.toString(s));
File[] files = file.listFiles();//返回File对象代表的目录下的文件,以File对象表示
System.out.println(Arrays.toString(files));
}
}
file.mkdir() 创建单级目录
file.mkdirs() 创建多级目录
public class Demo5 {
public static void main(String[] args) {
File file=new File("./test/aa/bb/cc");
//mkdir只能创建单级目录
boolean mkdir = file.mkdir();
//mkdirs可以创建多级目录
boolean mkdirs = file.mkdirs();
System.out.println(mkdirs);
}
}
文件的重命名可以起到移动的作用
file.renameTo()
public class Demo6 {
public static void main(String[] args) {
//文件的重命名可以起到移动的作用
File file=new File("./test.txt");
File newFile=new File("./src/test.txt");
System.out.println(file.renameTo(newFile));
System.out.println(file.getPath());
}
}
绝对路径:从根目录开始写的完整路径,定位唯一,不依赖当前所在的位置
相对路径:相对于当前的工作目录(当前的路径),来写的路径
文件IO
文件IO的输出输入方式通过数据流来实现
字节流
InputStream,读文件(输入)
OutputStream,写文件(输出)
字符流
Reader 读文件(输入)
Writer 写文件(输出)
字节流
InputStream
这里的创建对象,就相当于打开文件
![]()
但是又打开文件,就得有关闭文件
![]()
我们采用了try,finally,在结果加上关闭文件的操作
InputStream inputStream=null;
try {
inputStream=new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}finally {
inputStream.close();
}
但是这样的代码十分的不美观
我们采用try-with-resources(自动资源管理)
只要出了try的代码块,就会自动的调用close
要求代码块中的类实现Closeable或者AutoCloseable
InputStream中的read方法,可以使用-1表示读取完毕,有一次读取一个的方法参数配置,也有多个的,和指定偏移量的参数配置
public class Demo7 {
public static void main(String[] args) throws IOException {
// InputStream inputStream=null;
// try {
// inputStream=new FileInputStream("test.txt");
// } catch (FileNotFoundException e) {
// throw new RuntimeException(e);
// }finally {
// inputStream.close();
// }
//InputStream实现了Closeable,会自动的帮助你结束字节流
try (InputStream inputStream=new FileInputStream("test.txt")){
while (true){
//一次读一个字节
// int read = inputStream.read();
// if(read==-1){
// break;
// }
// System.out.printf("0x%x\n",read);
//一次读多个字节
byte[] data=new byte[3];//每次读三个字节
int n=inputStream.read(data);
if(n==-1){
break;
}
System.out.println("n="+n);
for (int i = 0; i < n; i++) {
System.out.printf("0x%x\n",data[i]);
}
}
}
}
}

OutputStream
outputStream的write方法在文件中可以一次性只写一个,或者多个

public class Demo8 {
public static void main(String[] args) {
// 这里面的true就是不会覆盖之前的内容,在后面追加
try(OutputStream outputStream=new FileOutputStream("./test.txt",true)) {
//一次写一个
// outputStream.write(1);
// outputStream.write(2);
// outputStream.write(3);
// outputStream.write(4);
//一次写多个
byte[] bytes=new byte[]{12,23,34};
outputStream.write(bytes);
InputStream inputStream=new FileInputStream("test.txt");
while (true){
int read = inputStream.read();
if (read==-1){
break;
}
System.out.printf("0x%x\n",read);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

字符流
Reader
读文件(输入)
![]()

public class Demo9 {
public static void main(String[] args) {
try(Reader reader=new FileReader("./test.txt")) {
while (true){
char[] chars=new char[1024];
int read = reader.read(chars);
if (read==-1){
break;
}
for (int i = 0; i < read; i++) {
System.out.print(chars[i]);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

Writer
Writer 写文件(输出)
BufferedWriter就是给Writer添加一个缓冲区,提高效率,BufferedWriter会先把数据写入内存的缓存区,等缓存满了或者调用flush()/close()时再一次性写入磁盘中
![]()
public class Demo10 {
public static void main(String[] args) {
try(Writer writer=new FileWriter("./test.txt",true);
BufferedWriter bufferedWriter=new BufferedWriter(writer)) {
bufferedWriter.write("我是谁");
Reader reader=new FileReader("./test.txt");
while (true){
char[] chars=new char[1024];
int read = reader.read(chars);
if (read==-1){
break;
}
for (int i = 0; i < read; i++) {
System.out.print(chars[i]);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
总结:
字节流和字符流两种代码都是对的,字节流读取到的时文件中原始的数据,字符流在读取的时候,会根据文件的内容编码格式,会自动进行解析(转码),转码会有性能的开销,所以字节流会比字符流快
转码的大概流程:
read一次,读到三个字节,返回的时候,针对3个字节进行转码,先拿3个字节查了一下utf8码表得到 ‘ 你 ’ read又把你这个汉字在unicode这个码表中再查一次,得到unicode的编码值,最终把unicode得到的编码值存储到char变量中(两字节)
专项练习1:扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件
/**
* 扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件
*/
public class Demo11 {
public static Scanner scanner=new Scanner(System.in);
public static void main(String[] args) {
System.out.println("请输入你要扫描的路径");
String rootFile = scanner.nextLine();
File files=new File(rootFile);
if (!files.isDirectory()){
System.out.println("你输入的不是目录");
}
System.out.print("请输入你要删除的关键词:");
String key=scanner.next();
scan(files,key);
}
private static void scan(File rootFile, String key) {
File[] file=rootFile.listFiles();
if (file==null){
System.out.println("该目录不存在");
return ;
}
for (File file1:file){
if(file1.isFile()){
delete(file1,key);
}else {
scan(file1,key);
}
}
}
private static void delete(File file1, String key) {
if (file1.getName().contains(key)){
System.out.println("请输入你是否要删除,这个文件,如果删除,请输入 y");
String next = scanner.next();
if(next.equalsIgnoreCase("y")){
file1.delete();
System.out.println("该文件已经删除");
}
}
}
}

专项练习2:进⾏普通⽂件的复制
/**
* 进⾏普通⽂件的复制
*/
public class Demo12 {
public static void main(String[] args) {
System.out.println("请输入你要复制文件的绝对路径/相对路径");
Scanner scanner=new Scanner(System.in);
String sourcePath=scanner.next();
File sourceFile=new File(sourcePath);
if (!sourceFile.exists()){
System.out.println("该文件不存在");
return;
}
if (!sourceFile.isFile()){
System.out.println("你输入的路径不是文件");
return;
}
System.out.println("请输入你要复制到的文件");
String destPath=scanner.next();
File destFile=new File(destPath);
if (!destFile.exists()){
System.out.println("该文件不存在");
return;
}
if (!destFile.isFile()){
System.out.println("你输入的路径不是文件");
return;
}
try(InputStream inputStream=new FileInputStream(sourceFile);
OutputStream outputStream=new FileOutputStream(destFile)) {
while (true){
byte[] bytes=new byte[1024];
int read = inputStream.read(bytes);
if (read==-1){
break;
}
outputStream.write(bytes,0,read);
System.out.println("复制成功");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}



专项练习3:扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)
/**
* 扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)
*/
public class Demo13 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要扫描的目录");
String next = scanner.nextLine();
File file=new File(next);
if(!file.isDirectory()){
System.out.println("你输入的不是目录,请重新输入");
}
System.out.println("请输入你要查询的关键字");
String key=scanner.next();
scan(file,key);
}
private static void scan(File file, String key) {
File[] files=file.listFiles();
if(files==null){
System.out.println("你输入的目录为空");
return;
}
for (File file1:files){
if (file1.isFile()){
//是普通文件
scanContent(file1,key);
}else {
//是目录
scan(file1,key);
}
}
}
private static void scanContent(File file1, String key) {
if (file1.getName().contains(key)){
System.out.println("该文件名中有关键字"+file1.getAbsolutePath());
return ;
}else {
StringBuffer stringBuffer=new StringBuffer();
try(Reader reader=new FileReader(file1)) {
while (true){
char[] chars=new char[1024];
int read = reader.read(chars);
if(read==-1){
break;
}
stringBuffer.append(chars,0,read);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
if(stringBuffer.indexOf(key)>=0){
System.out.println("该文件内容中有关键字"+file1.getAbsolutePath());
}
return ;
}
}
}


被折叠的 条评论
为什么被折叠?



