目录
1.文件
平时说的文件一般都是指存储在硬盘上的普通文件,形如txt,jpg,mp4,rar等这些文件都可以认为是普通文件,它们都是在硬盘上存储的.
在计算机中,文件可能是一个广义的概念就不只是包含普通文件,还可以包含目录,目录也是一种文件,称为目录文件
目录文件
exe文件
txt文件
1.1 文件分类
文件主要分为两类:文本文件和二进制文件
文本文件里面存储的是字符,二进制文件里面存储的是字节
文本文件本质上也是存字节的,但是文本文件中,相邻的字节在一起正好能构成一个个的字符,字节和字节之间是有联系的.
二进制文件存储的是字节,这种的话字节和字节之间就完全没啥关系了
1.2 判断一个文件是文本和二进制:
用记事本打开,如果打开之后是乱码,就是二进制文件,不是乱码就是文本,如下图所示:
用记事本打开图片,显示乱码,图片就是二进制文件.
打开文本没有显示乱码是字符,就是文本文件
1.3 目录结构
计算机里保存管理文件,是通过操作系统中的“文件系统”这样的模块来负责的,文件系统中,一般是通过“树形”结构来组织磁盘上的目录和文件的.
整体的文件系统,就是这种树形结构.
如果是一个普通文件,就是树的叶子节点.
如果是一个目录文件,目录中就可以包含子树,这个目录就是非叶子节点.
这个树每个节点上的子树都可以有 N 个这就是一个N叉树了.
结构如下图所示:
1.4 绝对路径和相对路径
绝对路径:
绝对路径是以盘符开头的路径,比如:
D:\anaconda\condabin
D:\游戏\Hearthstone
相对路径:
相对路径是以 . 或者 . . 开头的,其中 .表示当前路径, . . 表示当前目录的父目录(上级路径)
相对路径必须要有一个基准目录为参考,相对路径就是从基准目录出发,按照基准目录的路径找到的对应文件
比如以 D:\Java code\newcode 为基准
找src文件夹: ./src
比如以 D:\Java code\newcode\src 为基准
找src文件夹: . ./src
2.File操作
Java 中操作文件是通过“文件资源管理器”能够完成的一些功能,比如1)列出目录中有哪些文件,2)创建文件,3)创建目录,4)删除文件,5)重命名文件
在Java 中提供了一个 File 类,通过这个类来完成上述操作.
File 的构造方法能够传入一个路径来指定一个文件,这个路径可以是绝对路径也可以是相对路径
File构造方法填入绝对路径:
File构造方法填入相对路径:
相对路径一定得先明确一个“基准路径",上述代码中,基准路径由是运行这个 java 程序来确定
第一种通过命令行的方式,此时执行命令所在的目录,就是基准路径,实际上不考虑这个情况,毕竟当前不需要通过命令来运行 java 程序
如下图所示,在下图指定的路径运行程序,基准路径就是下图路径
第二种是通过IDEA 的方式来运行程序,此时基准路径就是当前 java 项目所在的路径,如下图所示,显示的是当前java项目所在的路径
在IDEA 中直接运行,基准路径就是上述目录
此处写的"./test.txt"在 IDEA 中运行,意思就是找newcode目录下的 test.txt
2.1 File类使用
public class demo1 {
public static void main(String[] args) throws IOException {
File f=new File("D:\\Java code\\newcode");
System.out.println(f.getParent()); //获取文件父类
System.out.println(f.getName()); //获取文件名
System.out.println(f.getPath()); //获取文件路径(构造File时指定的路径)
System.out.println(f.getAbsolutePath()); //获取文件绝对路径
System.out.println(f.getCanonicalPath()); //获取文件绝对路径
System.out.println("====================");
File f2=new File("./test.txt");
System.out.println(f2.getParent());//获取文件父类
System.out.println(f2.getName());//获取文件名
System.out.println(f2.getPath());//获取文件路径(构造File时指定的路径)
System.out.println(f2.getAbsolutePath());//获取文件绝对路径
System.out.println(f2.getCanonicalPath());//获取文件绝对路径
}
}
. 仍然是表示当前目录,也就是 newcode这一级目录,完全可以把 . 给去掉
2.2 文件创建和删除
public class demo4 {
public static void main(String[] args) {
File f=new File("./test.txt");
System.out.println(f.exists()); //是否存在
System.out.println(f.isDirectory()); //是否是目录
System.out.println(f.isFile()); //是否是文件
}
}
public class demo2 {
public static void main(String[] args) {
File f=new File("./test");
System.out.println(f.exists());
f.mkdir();
System.out.println("创建成功");
System.out.println(f.exists());
System.out.println(f.isDirectory());
}
}
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./test.txt");
System.out.println(f.exists());
f.createNewFile();
System.out.println("创建成功");
System.out.println(f.exists());
System.out.println(f.isFile());
}
}
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./test.txt");
f.delete(); //删除文件
}
}
创建多级目录
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./a/b/c/d");
f.mkdirs();
}
}
查看目录
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./src");
System.out.println(Arrays.toString(f.list()));
}
}
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./src");
System.out.println(Arrays.toString(f.list()));
System.out.println(Arrays.toString(f.listFiles()));
}
}
修改文件名
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./test");
File f2=new File("./t");
f.renameTo(f2);
}
}
修改文件名
public class demo2 {
public static void main(String[] args) throws IOException {
File f=new File("./test.txt");
f.createNewFile();
File f2=new File("./tt.txt");
f.renameTo(f2);
}
}
3.文件的读写操作
3.1 Inputstream读取字节
记事本里放的是abcde,下面的代码都是读取当前的内容
public class demo5 {
public static void main(String[] args) throws IOException {
//1.创建对象,同时打开文件
InputStream inputStream=new FileInputStream("./test.txt");
try{
//2.尝试一个字节一个字节的读取,直接读取到文件末尾
while(true){
int b=inputStream.read();
if(b==-1){
break;
}
System.out.println(b);
}
}catch(IOException e){
e.printStackTrace();
}finally {
//3.释放资源
inputStream.close();
}
}
}
这是读出来的数字,就是每个字符的ASCII码值,由于这些英文字符,本身就是一个字节的,这里按照字节读取的效果就是如此
上述的代码可以简化
public class demo6 {
public static void main(String[] args) {
try(InputStream inputStream=new FileInputStream("./test.txt")){
while(true){
int a=inputStream.read();
if(a==-1){
break;
}
System.out.println(a);
}}
catch (IOException e){
e.printStackTrace();
}
}
}
** 在这个代码中,没有显式的调用 close但是 try 会帮我们自动调用,当代码执行完这里的 try 语句块之后,就会自动的调用 close,得符合一定的条件,才能放到 try () 中实现 Closeable 这个 interface所有的流对象, 都实现了 Closeable~~所以就可以直接放了**
3.2 InputStream一次性读取多个字节
使用数组一次性读取多个字节
public class demo7 {
public static void main(String[] args) {
//一次性读取多个字节
try(InputStream inputStream= new FileInputStream("./test.txt")){
while(true){
byte[] buffer=new byte[1000];
int b=inputStream.read(buffer);
if(b==-1) {
break;
}
for (int i = 0; i < b; i++) {
System.out.println(buffer[i]);
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
3.3 InputStream写入字节
outputStream.write() , 一次只能写入一个字节
public class demo8 {
public static void main(String[] args) {
try(FileOutputStream outputStream=new FileOutputStream("./test.txt")){
outputStream.write(49);
outputStream.write(50);
outputStream.write(51);
}catch (IOException e){
e.printStackTrace();
}
}
}
public class demo8 {
public static void main(String[] args) {
try(FileOutputStream outputStream=new FileOutputStream("./test.txt")){
// outputStream.write(49);
// outputStream.write(50);
// outputStream.write(51);
byte[] buffer= new byte[]{49,50,51};
outputStream.write(buffer);
}catch (IOException e){
e.printStackTrace();
}
}
}
3.4 Reader读取字符
public class demo9 {
public static void main(String[] args) throws IOException {
//char数组读取字符
try(Reader reader=new FileReader("./test.txt")){
while(true){
char[] arr=new char[1000];
int len= reader.read(arr);
if(len==-1){
break;
}
for(int i=0;i<len;i++){
System.out.println(arr[i]);
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
Reader写字符
一次写入一个字符
public class demo11 {
public static void main(String[] args) {
try(FileWriter writer =new FileWriter("./test.txt")){
writer.write(97);
writer.write(98);
writer.write(99);
writer.write("abcd");
}catch (IOException e){
e.printStackTrace();
}
}
}
一次写入多个字符
public class demo11 {
public static void main(String[] args) {
try(FileWriter writer =new FileWriter("./test.txt")){
// writer.write(97);
// writer.write(98);
// writer.write(99);
char[] arr=new char[]{'a','b','c','d'};
writer.write(arr);
}catch (IOException e){
e.printStackTrace();
}
}
}
3.6 OutputStream
public class Outputdemo {
public static void main(String[] args) {
try(OutputStream outputStream=new FileOutputStream("D:/1.txt")){
outputStream.write(97);
outputStream.write(98);
outputStream.write(99);
}catch (IOException e){
e.printStackTrace();
}
}
}
4.练习
4.1 练习1
public class demo12 {
public static void main(String[] args) throws IOException {
//1.先输入目录和要删除的文件
Scanner sc=new Scanner(System.in);
System.out.println("请输入要查询的目录");
String RootDirpath=sc.next();
System.out.println("请输入要删除的文件:");
String DeleteFile=sc.next();
File RootDir=new File(RootDirpath);
if(!(RootDir.isDirectory())){
System.out.println("扫描路径有误,请重新输入");
return;
}
Scan(RootDir,DeleteFile);
}
//2.遍历目录,把指定文件的子目录和文件都扫描一遍,看是否包含要删除的文件
private static void Scan(File rootDir, String deleteFile) throws IOException {
// 列出rootDir里面有哪些文件
File[] files=rootDir.listFiles();
if(files==null){
return;
}
//2.遍历当前列出的这些内容,如果是普通文件,就检测文件名是否是要删除的文件
//如果是目录,就递归的进行遍历
for(File f:files){
if(f.isFile()){
//如果包含要删除的关键字就删除文件
if(f.getName().contains(deleteFile)){
deleteFile(f);
}
}else if(f.isDirectory()){
Scan(f,deleteFile);
}
}
}
private static void deleteFile(File f) throws IOException {
System.out.println(f.getCanonicalPath()+"是否要删除");
Scanner sc=new Scanner(System.in);
System.out.println("请确认是否要删除,y表示确认删除,n表示取消删除");
String choice=sc.next();
if(choice.equals("Y")|| choice.equals("y")){
f.delete();
System.out.println("删除成功");
}else{
System.out.println("取消删除");
}
}
}
4.2 复制文件
public class demo13 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入源路径");
String Root=sc.next();
System.out.println("请输入要复制的路径");
String des=sc.next();
File f=new File(Root);
if(!f.isFile()){
System.out.println("输入的路径不正确");
return;
}
try(InputStream inputStream= new FileInputStream(Root)){
try(OutputStream outputStream =new FileOutputStream(des)){
//读inputStream中的数据,写入OutputStream
byte[] buffer=new byte[1000];
while(true){
int len=inputStream.read(buffer);
if(len==-1){
break;
}
outputStream.write(buffer,0,len);
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
4.3 文件内容的查找
package File;
import java.io.*;
import java.util.Scanner;
public class demo14 {
public static void main(String[] args) throws IOException {
//1.输入要扫描的文件路径
Scanner sc=new Scanner(System.in);
System.out.println("请输入要扫描的路径");
String root=sc.next();
System.out.println("请输入要查找的关键词");
String word=sc.next();
File rootDir=new File(root);
if(!rootDir.isDirectory()){
System.out.println("输入的路径有误");
return;
}
//2.递归遍历
scanDir(rootDir,word);
}
private static void scanDir(File rootDir, String word) throws IOException {
File[] files=rootDir.listFiles();
if(files==null){
return;
}
for(File f:files){
if(f.isFile()){
if(containsWord(f,word)){
System.out.println(f.getCanonicalPath());
}
}else if(f.isDirectory()){
scanDir(f,word);
}
}
}
private static boolean containsWord(File f,String word){
StringBuilder stringBuilder=new StringBuilder();
//读取f的内容,放入stringBuilder里
try(Reader reader=new FileReader(f)) {
char[] buffer=new char[1000];
while(true){
int len=reader.read(buffer);
if(len==-1){
break;
}
stringBuilder.append(buffer,0,len);
}
}catch (IOException e) {
}
return stringBuilder.indexOf(word)!=-1;
}
}