黑马程序员——异常和IO流01

来源:互联网 发布:淘宝电子商务运营 编辑:程序博客网 时间:2024/05/29 06:27

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——

一、异常

 

异常就是程序出现的不正常的情况。

 

1.异常的体系

Throwable

|--Error严重问题,我们不处理。

|--Exception

|--RuntimeException运行期异常,我们需要修正代码

|--非RuntimeException 编译期异常,必须处理的,否则程序编译不通过

 

2.异常的处理

1)JVM的默认处理

把异常的名称,原因,位置等信息输出在控制台,但是呢程序不能继续执行了。

2)自己处理

A:try...catch...finally:自己编写处理代码,后面的程序可以继续执行

B:throws:把自己处理不了的,在方法上声明,告诉调用者,这里有问题

 

3.自定义异常

继承自Exception或者RuntimeException,只需要提供无参构造和一个带参构造即可

 

4.异常的注意点

1)父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常 

2)父的方法没有异常抛出,子的重写方法不能有异常抛出

3)父的方法抛出多个异常,子的重写方法必须比父少或者小

4)编译期异常和运行期异常的区别?

编译期异常必须要处理的,否则编译不通过

运行期异常可以不处理,也可以处理

5)throw和throws是的区别

throw:

在方法体中,后面跟的是异常对象名,并且只能是一个

throw抛出的是一个异常对象,说明这里肯定有一个异常产生了

throws:

在方法声明上,后面跟的是异常的类名,可以是多个

throws是声明方法有异常,是一种可能性,这个异常并不一定会产生

 

5.finally关键字

1)finally用于释放资源,它的代码永远会执行。特殊情况:在执行到finally之前jvm退出了

2)final,finally,finalize的区别:

A:final,修饰符(关键字)

如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。

将变量或方法声明为final,可以保证它们在使用中不被改变。

被声明为final的方法只能使用,不能重载。 

 

B:finally,再异常处理时提供finally 块来执行任何清除操作。

如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 

C:finalize,方法名。

finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。

 

3)如果在catch里面有return,finally还仍然执行,并且是在return中间执行的。

首先return时把要return的值先处理好,然后再执行finally里的代码,

执行后再将缓存好的要return的值返回

 


二、File

 

IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件

 

1.构造方法

1)File file = newFile("e:\\demo\\a.txt"); 根据一个路径得到File对象

2)File file = newFile("e:\\demo","a.txt"); 根据一个目录和一个子文件/目录得到File对象

3)File file3 = newFile("e:\\demo"); 根据一个目录得到File对象(文件夹)

4)File file = newFile(file,"a.txt"); 根据一个父File对象和一个子文件/目录得到File对象

 

2.File类的功能

1)创建功能:

public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了

public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了

public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来

 

2)删除功能:public booleandelete()

 

3)重命名功能:public booleanrenameTo(File dest)

如果路径名相同,就是改名。

如果路径名不同,就是改名并剪切。

 

4)判断功能:

public boolean isDirectory():判断是否是目录

public boolean isFile():判断是否是文件

public boolean exists():判断是否存在

public boolean canRead():判断是否可读

public boolean canWrite():判断是否可写

public boolean isHidden():判断是否隐藏

 

5)获取功能:

public String getAbsolutePath():获取绝对路径

public String getPath():获取相对路径

public String getName():获取名称

public long length():获取长度。字节数

public long lastModified():获取最后一次的修改时间,毫秒值

 

 

6)高级获取功能:

public String[] list():获取指定目录下的所有文件或者文件夹的名称数组

public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组

 

7)过滤器功能:

public String[] list(FilenameFilter filter)

public File[] listFiles(FilenameFilterfilter)

 

 

3.案例:

输出指定目录下指定后缀名的文件名称 

import java.io.File; 

import java.io.FilenameFilter; 

 

/*

 * 判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称

 * A:先获取所有的,然后遍历的时候,依次判断,如果满足条件就输出。

 * B:获取的时候就已经是满足条件的了,然后输出即可。

 * 

 * 要想实现这个效果,就必须学习一个接口:文件名称过滤器

 *public String[] list(FilenameFilter filter)

 *public File[] listFiles(FilenameFilter filter)

 */ 

public class FileDemo2 { 

   public static void main(String[] args) { 

       // 封装e判断目录 

       File file = new File("e:\\"); 

 

       // 获取该目录下所有文件或者文件夹的String数组 

       // public String[] list(FilenameFilter filter) 

       String[] strArray = file.list(new FilenameFilter() { 

           @Override 

           public boolean accept(File dir, String name) { 

                // return false; 

                // return true; 

                // 通过这个测试,我们就知道了,到底把这个文件或者文件夹的名称加不加到数组中,取决于这里的返回值是true还是false 

                // 所以,这个的true或者false应该是我们通过某种判断得到的 

                // System.out.println(dir +"---" + name); 

                // File file = new File(dir,name); 

                // //System.out.println(file); 

                // boolean flag =file.isFile(); 

                // boolean flag2 =name.endsWith(".jpg"); 

                // return flag && flag2; 

                return new File(dir,name).isFile() && name.endsWith(".jpg"); 

           } 

       }); 

 

       // 遍历 

       for (String s : strArray) { 

           System.out.println(s); 

       } 

   } 

 

三、递归

 

方法定义中调用方法本身的现象叫做递归

 

1.递归的注意事项;

1)要有出口,否则就是死递归

2)次数不能过多,否则内存溢出

3)构造方法不能递归使用


2.递归的案例:

递归输出指定目录下所有指定后缀名的文件绝对路径

import java.io.File; 

 

/*

 * 需求:请大家把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。

 * 

 * 分析:

 *     A:封装目录

 *     B:获取该目录下所有的文件或者文件夹的File数组

 *     C:遍历该File数组,得到每一个File对象

 *     D:判断该File对象是否是文件夹

 *         是:回到B

 *         否:继续判断是否以.java结尾

 *             是:就输出该文件的绝对路径

 *             否:不搭理它

 */ 

public class FilePathDemo { 

   public static void main(String[] args) { 

       // 封装目录 

       File srcFolder = new File("E:\\JavaSE"); 

 

       // 递归功能实现 

       getAllJavaFilePaths(srcFolder); 

   } 

 

   private static void getAllJavaFilePaths(File srcFolder) { 

       // 获取该目录下所有的文件或者文件夹的File数组 

       File[] fileArray = srcFolder.listFiles(); 

 

       // 遍历该File数组,得到每一个File对象 

       for (File file : fileArray) { 

           // 判断该File对象是否是文件夹 

           if (file.isDirectory()) { 

                getAllJavaFilePaths(file); 

           } else { 

                // 继续判断是否以.java结尾 

                if(file.getName().endsWith(".java")) { 

                    // 就输出该文件的绝对路径 

                   System.out.println(file.getAbsolutePath()); 

                } 

           } 

       } 

   } 

}

 

四、IO流概述与字节流

IO用于在设备间进行数据传输的操作 

1.分类:

1)流向

输入流读取数据

输出流写出数据

2)数据类型

字节流

字节输入流

字节输出流

字符流

字符输入流

字符输出流

3)注意:

A:如果没有明确说明按照什么分,默认按照数据类型分。

B:除非文件用记事本打开能够读懂,才采用字符流,否则建议使用字节流。

 

2.FileOutputStream写出数据

1)构造方法:

FileOutputStream(File file) 

FileOutputStream(String name)

FileOutputStream(String name, booleanappend);

 

1)操作步骤

A:创建字节输出流对象

B:调用write()方法

C:释放资源

 

2)代码体现:

FileOutputStream fos = new FileOutputStream("fos.txt");  

fos.write("hello".getBytes());  

fos.close();  

 

3)注意

A:创建字节输出流对象所做的事情

a:调用系统功能去创建文件

b:创建fos对象

b:把fos对象指向这个文件

B:close()的作用:释放资源

a:让流对象变成垃圾,这样就可以被垃圾回收器回收了

b:通知系统去释放跟该文件相关的资源

C:实现数据的换行方式:

写入换行符号:

windows:\r\n

linux:\n

Mac:\r

D:实现数据的追加写入的方式:用构造方法带第二个参数是true的情况即可

 

4)案例

public class FileOutputStreamDemo3 { 

   public static void main(String[] args) throws IOException { 

       // 创建字节输出流对象 

       // FileOutputStream fos = newFileOutputStream("fos3.txt"); 

       // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处 

       FileOutputStream fos = new FileOutputStream("fos3.txt",true); 

 

       // 写数据 

       for (int x = 0; x < 10; x++) { 

           fos.write(("hello" + x).getBytes()); 

           fos.write("\r\n".getBytes()); 

       } 

 

       // 释放资源 

       fos.close(); 

   } 

 

3.FileInputStream读取数据

1)构造方法:

FileInputStream(String name)

 

2)操作步骤

A:创建字节输入流对象

B:调用read()方法

C:释放资源

 

3)代码体现:

FileInputStream fis = newFileInputStream("fos.txt"); 

 

// 方式1 

int by = 0; 

while ((by = fis.read()) != -1) { 

   System.out.print((char) by); 

 

// 方式2 

byte[] bys = new byte[1024]; 

int len = 0; 

while ((len = fis.read(bys)) != -1) { 

   System.out.print(new String(bys, 0, len)); 

 

fis.close(); 

 

4.字节缓冲区流

java开始在设计的时候,考虑到了一次读一个字节速度很慢,就专门提供了带缓冲区的字节类。

这种类被称为:缓冲区类(高效类)

构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了

1)BufferedOutputStream:写数据

构造方法:BufferedInputStream(InputStream in)

2)BufferedInputStream:读数据

构造方法:BufferedOutputStream(OutputStream out)

 

5.案例

package cn.itcast_06; 

 

import java.io.BufferedInputStream; 

import java.io.BufferedOutputStream; 

import java.io.FileInputStream; 

import java.io.FileOutputStream; 

import java.io.IOException; 

 

/*

 * 需求:把e:\\test.mp4复制到当前项目目录下的copy.mp4中

 * 

 * 字节流四种方式复制文件:

 * 基本字节流一次读写一个字节:   共耗时:117000毫秒

 * 基本字节流一次读写一个字节数组: 共耗时:150毫秒

 * 高效字节流一次读写一个字节: 共耗时:1100毫秒

 * 高效字节流一次读写一个字节数组: 共耗时:40毫秒

 */ 

public class CopyMp4Demo { 

   public static void main(String[] args) throws IOException { 

       long start = System.currentTimeMillis(); 

       // method1("e:\\test.mp4", "copy1.mp4"); 

       // method2("e:\\test.mp4", "copy2.mp4"); 

       // method3("e:\\test.mp4", "copy3.mp4"); 

       method4("e:\\test.mp4", "copy4.mp4"); 

       long end = System.currentTimeMillis(); 

       System.out.println("共耗时:" + (end - start) + "毫秒"); 

   } 

 

   // 高效字节流一次读写一个字节数组: 

   public static void method4(String srcString, String destString) 

           throws IOException { 

       BufferedInputStream bis = new BufferedInputStream(newFileInputStream( 

                srcString)); 

       BufferedOutputStream bos = new BufferedOutputStream( 

                new FileOutputStream(destString)); 

 

       byte[] bys = new byte[1024]; 

       int len = 0; 

       while ((len = bis.read(bys)) != -1) { 

           bos.write(bys, 0, len); 

       } 

 

       bos.close(); 

       bis.close(); 

   } 

 

   // 高效字节流一次读写一个字节: 

    public static void method3(String srcString,String destString) 

           throws IOException { 

       BufferedInputStream bis = new BufferedInputStream(newFileInputStream( 

                srcString)); 

       BufferedOutputStream bos = new BufferedOutputStream( 

                newFileOutputStream(destString)); 

 

       int by = 0; 

       while ((by = bis.read()) != -1) { 

           bos.write(by); 

 

       } 

 

       bos.close(); 

       bis.close(); 

   } 

 

   // 基本字节流一次读写一个字节数组 

   public static void method2(String srcString, String destString) 

           throws IOException { 

       FileInputStream fis = new FileInputStream(srcString); 

       FileOutputStream fos = new FileOutputStream(destString); 

 

       byte[] bys = new byte[1024]; 

       int len = 0; 

       while ((len = fis.read(bys)) != -1) { 

           fos.write(bys, 0, len); 

       } 

 

       fos.close(); 

       fis.close(); 

   } 

 

   // 基本字节流一次读写一个字节 

    publicstatic void method1(String srcString, String destString) 

           throws IOException { 

       FileInputStream fis = new FileInputStream(srcString); 

       FileOutputStream fos = new FileOutputStream(destString); 

 

       int by = 0; 

       while ((by = fis.read()) != -1) { 

           fos.write(by); 

       } 

 

       fos.close(); 

       fis.close(); 

   } 

}

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——
0 0
原创粉丝点击