JAVA基础09—文件File和异常处理

本文详细介绍了JAVA中的文件API,包括File类的创建、路径处理、文件操作及流的使用。同时,深入探讨了异常处理机制,如try-catch-finally语句、异常分类、自定义异常,以及在实际编程中的应用。通过实例展示了文件的创建、读写、删除和目录操作,以及异常捕获和处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


学习常用API的过程中,JAVA的文件API File 是文件、目录常用API,是我们学习API的必经之路,也是学习流的一个很好的开端。

1.File 文件

1.1 创建File 对象

1.1.1 绝对、相对路径

文件File中要传的参数少不了文件的路径。
绝对路径、相对路径相信我们已不陌生,都是表示具体文件、目录的路径。下面我们稍微复习一下:

绝对路径是指基于某个操作系统下,从根目录算起的路径,是最完整的表达方式之一:例如
C:\Users\accountNumber\Desktop\Tools\tools.exe
举个例子:

    File f = new File("C:\\Users\\accountNumber\\Desktop\\Tools\\tools.exe");
    //输出该文件是否存在的boolean结果
    System.out.println(f.exists());

相对路径是指当前文件、程序下的相对路径,绝对路径里的冗长目录路径可以用"./"代替,沿用上述例子的路径,相对路径可以表达为:

		File f = new File("./tools.exe");
		System.out.println(f.exists());

其中"./"可以省略:

        File f = new File("tools.exe");
		System.out.println(f.exists());

注意,为了兼容LinuxOS等其他OS的路径表示规则,我们实际开发中常用斜杠"/"来表示路径的斜杠,而不是Windows系统复制路径时默认的反斜杠。

1.1.2 创建对象

操作文件通常要通过文件对象,参数为文件的目标路径。
为了程序在不同环境(OS、服务器等)的复用性,强烈建议使用相对路径。

    File f = new File("[目标路径]");

1.2 File常用方法

1.2.1 判断文件是否存在

    File f = new File("tools.exe");
    //exists方法为判断文件是否存在的方法,返回的是boolean值
	System.out.println(f.exists());

1.2.2 创建文件

创建文件方法createNewFile ,要注意:此时要抛异常。具体异常处理方式在下面的段落介绍。

public static void main(String[] args) throws IOException {
        //当前目录下新建一个文件
        File file = new File("./test.txt");
        if(file.exists()){
            //若该文件已存在
            System.out.println("该文件已存在!");
        }else{
            //若文件不存在,创建文件
            file.createNewFile();
        }
    }

1.2.3 创建目录

即创建文件夹。

     //当前目录下创建一个目录
        //实际开发中,相对路径的“./可以省略”
        File dir = new File(".abc/sdd/demo.abc");

        if(dir.exists()){
            System.out.println("改目录已存在");
        }else{
            dir.mkdirs();
            System.out.println("该目录已创建");
        }

    }

1.2.4 判断是否为文件夹或文件

isFile()判断是否为文件

     File f = new File("demo.txt");
        System.out.println(f.isFile());
        

isDirectory()判断是否为文件夹

 File f = new File("demo.txt");
    System.out.println(f.isDirectory());

1.2.5 删除文件、目录

delete()方法,该方法既可以删除文件,也可以删除目录。

删除文件:

     File file = new File("test.txt");
        if(file.exists()){
            file.delete();
            System.out.println("该文件已删除");
        }else{
            System.out.println("该文件不存在!");
        }
    }

删除目录:

     //将当前目录下的demo目录删除
        File dir = new File(".abc");

        //删除
        if(dir.exists()){
            //必须是空目录
            dir.delete();
            System.out.println("该目录已删除");
        }else{
            System.out.println("该目录不存在");
        }

1.2.6 获取当前文件夹列表

listFiles() 方法返回一个文件类型数组

    File dir = new File(".");
        if(dir.isDirectory()){
            File [] subs = dir.listFiles();
            for (File sub : subs) {
                System.out.println(sub);
            }
        }

listFiles可以传参,进行文件过滤

    //参数用filter
     File [] files = dir.listFiles(filter);

其中Filefilter是个接口,要实现,我们可以使用匿名内部类来实例化它的实现类,举个例子:

    //获取当前文件夹的所有目录
     File dir = new File(".");
        if(dir.isDirectory()){
            FileFilter filter = new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isDirectory();
                }
            };
            File [] files = dir.listFiles(filter);
            for(File f : files){
                System.out.println(f);
            }
        }

1.3 文件流

程序往往通过流来与外部设备进行数据交换。对于文件,JAVA使用FileInputStream和FileOutputStream来对文件进行读写。

对IO流的具体学习,可参见百度

1.3.1 FileInputStream

作用:读取文件

例子:

     FileInputStream fis = new FileInputStream("./test.txt");
        /**
         * 读取规则,一位一位地读,输出低八位,余位补0,读到末尾返回-1的补码
         * 用基本类型接收的时候,会输出该位的二进制
         * */
        int index = 24;
        while(index > 0 ){
            char d = (char) fis.read();
            System.out.println(d);
            index --;
        }
        fis.close();

1.3.2 FileOutputStream

作用:写入文件

例子:

 //向文件test.txt写入一个字节
        FileOutputStream fos = new FileOutputStream("./test.txt");
        //以程序为原点,要将东西写入文件,使用输出流
        /*
         * void write (int d)
         * 写出一个字节,写出的内容是给定的int值对应的二进制的低八位
         * */
        int index = 26;
        while(index >0){
            fos.write(index+97);
            index --;
        }
        System.out.println("写出完毕");
        fos.close();

        File f = new File("./test.txt");
        if(f.isFile()){
            System.out.println(f.length());
        }

1.3.3 文件复制

合理使用文件流可以实现文件复制。

举个例子:

        //定义流
        long now = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("./CpDemoPlus.mp4");
        FileOutputStream fos = new FileOutputStream("./CpDemoPlus2.mp4");

        //用比较简洁的方式复制
        int index;
        while ((index = fis.read())!=-1){
            fos.write(index);
        }

        System.out.println("复制完毕!");
        fis.close();
        fos.close();
        long after = System.currentTimeMillis();
        System.out.println("复制经历了"+(after-now)+"ms");

2.Exception 异常

异常在我们学习过程中随处可见,例如我们操作数组时,不小心就会出现数组下表越界异常:IndexOutOfBoundsException.
在上面文件与文件流的学习中,我们也遇到了异常,在此我们详细介绍一下异常。

2.1 异常处理

2.1.1 异常分类

Exception 和 Error,他们都是Throwable类的派生类,都实现了Serializable接口。

其中,Exception 通常用于表示用户非法输入、文件损坏等非法情况导致的异常,是程序级别的一些错误。
Error则表示更严重的,系统级的一些错误,如程序运行时一些环境导致的错误。

文字上我们通常将异常表达为:错误、运行时异常与非运行时异常。错误与运行时异常通常我们不需要捕获,非运行时异常则需要我们进行显式的捕获或者抛出。

因此我们在编写程序的过程中,更多地会关注Exception异常。

2.1.2 try-catch-finally语句 捕获异常

语法如下:

   try{
       可能会发生异常的代码
   }catch(ExceptionType e){
       发生异常后执行的语句,通常是解决方案或者将异常输出
   }finally{
       无论以上代码是否执行,都会执行的语句,通常用于释放资源,如文件流的close
   }

一般情况下,如果没有必须执行的语句,使用try-catch即可,其中catch可以连用,即catch后可以连着一个catch

以下是例子:

    /**单个try-catch解决单个异常问题*/
    public static void main(String[] args) {
		// TODO Auto-generated method stub
		File f = new File("./tools.exe");
	
		//输出一下观察该文件是否存在
		System.out.println("该文件是否存在"+f.exists());
		
		//创建文件流,若该文件存在,创建文件输入流,否则输出该文件不存在
		try {
			//尝试执行的代码
			FileInputStream fis = new FileInputStream(f);
			
		}catch(FileNotFoundException e){
			System.out.println("该文件不存在");
			//输出异常信息
			e.printStackTrace();
		}
	}

多个catch连用:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 手动做两件会出现不同异常的事情:
		
		int c [] = {1,2,3};
		File f = new File("./tools.exe");
			
		try {
			FileInputStream fis = new FileInputStream(f);
			System.out.println(c[4]);
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("数组下标越界!");
		   //以下使用catch连用捕获异常
		}catch(FileNotFoundException e) {
			System.out.println("文件不存在!请检查路径");
		}
	
	}

catch里的异常类型放在一块:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 手动做两件会出现不同异常的事情:

		int c[] = { 1, 2, 3 };
		File f = new File("./tools.exe");

		try {
			FileInputStream fis = new FileInputStream(f);
			System.out.println(c[4]);
		} catch (ArrayIndexOutOfBoundsException | FileNotFoundException e) {
			System.out.println("出現了異常!");
		}
	}

当异常类型特别多的时候,可以选用最大的Exception捕获

public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 手动做两件会出现不同异常的事情:

		int c[] = { 1, 2, 3 };
		File f = new File("./tools.exe");

		try {
			FileInputStream fis = new FileInputStream(f);
			System.out.println(c[4]);
		} catch (Exception e) {
			System.out.println("出現了異常!");
		}
	}

try-catch-finally连用,finally里的代码块必须执行

    public static void main(String[] args) {
		// TODO Auto-generated method stub
		File f = new File("./tools.exe");

		try {
			FileInputStream fis = new FileInputStream(f);
		} catch (Exception e) {
			System.out.println("出現了異常!");
		} finally {
			System.out.println("无论上述代码是否异常,都会执行的代码");
		}
	}

2.1.3 抛出异常

关键字:throw 和 throws

throw 通常在方法内,throws通常在方法声明上。

throw
public static void main(String[] args) {
		// TODO Auto-generated method stub
		int i[] = {1,2,3};
		
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入想要查询的数组下标");
		 
        int index = sc.nextInt();
		
		//举个小例子,此处可能出现越界
		if(index > 2) {
			throw new ArrayIndexOutOfBoundsException();
		}else {
			System.out.println(i[index]);
		}
	}

实际开发中,一些程序可以运行的情况,但不符合业务逻辑,又不需要就地解决的问题,就可以通过throw抛出异常。

throws

当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理这个异常。
例如我们阅读源码时,会发现在一些类里面,已经给我们throws了一些异常

 public void close() throws IOException {}

处理办法包括:try-catch-finally在当前代码块解决、继续throws抛出给上层程序解决。

注意,最好不要在main方法声明处throws异常,对JAVA虚拟机来说,main方法是程序的入口,也是最高曾的程序,
如果交给main throws ,又发生异常时,JVM会kill掉当前main方法,导致整个程序运行结束。

    public class ThrowsDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		useMethodDemo();
	}
	
	public static void useMethodDemo() {
		//使用该方法时,必须选择处理异常
		try {
			defineThrowsMethod();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	} 
	
	public static void defineThrowsMethod() throws IOException{
		File f= new File("./tools.exe");
		
		FileInputStream fis = new FileInputStream(f);
		
		//读一个低八位
		int a = fis.read();
		System.out.println(a);
	}

}

2.1.4 自定义异常

我们还可以自定义异常,需要创建该异常的类,继承Exception并实现构造方法。举个例子:

public class ExceptionDefineByMyself extends Exception {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public ExceptionDefineByMyself() {
		super();
		// TODO Auto-generated constructor stub
	}

	public ExceptionDefineByMyself(String message, Throwable cause, boolean enableSuppression,
			boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public ExceptionDefineByMyself(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public ExceptionDefineByMyself(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public ExceptionDefineByMyself(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
    public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			testMethod();
		} catch (ExceptionDefineByMyself e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void testMethod() throws ExceptionDefineByMyself {
		int i = new Scanner(System.in).nextInt();
		if(i<0) {
			throw new ExceptionDefineByMyself();
		}
	}

3.总结

本文涉及的知识点比较多,首先我们学习了JAVA中操作文件的API:File,初步了解了文件的常用方法,初步学习了文件流;在学习文件的过程中,我们发现IDE会强制我们进行异常处理,于是我们就学习了异常处理机制:捕获异常现场处理、抛异常交给上层处理、自定义异常。

我们下一篇见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值