黑马程序员__异常处理_File类_IO流之字节读写

来源:互联网 发布:数据资产管理 石油 编辑:程序博客网 时间:2024/05/16 17:07


-------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------




一、异常

(1)就是程序运行过程中,遇到了问题,这就叫异常

(2)异常的体系

Throwable 其实应该分三种

Error

通常出现重大问题如:服务器宕机数据库崩溃等。

不编写针对代码对其处理。

Exception

除了 RuntimeException 和其所有子类,其他所有的异常类都是在编译的时候必须要处理的

要么try,要么抛

RuntimeException

RuntimeException和其所有的子类,都不会在编译的时候报异常,而是在运行时报异常,这时候我们

就需要回头看看我们的代码是否有问题,比如角标越界,空指针等。

(3)Throwable Runnable

1:getMessage() :返回此 throwable 的详细消息字符串

[java] view plaincopy
  1. String detailMessage;  
  2.         Throwable(){}  
  3.   
  4.         Throwable(String message) {  
  5.             this.detailMessage = message;  
  6.         }  
  7.   
  8.         public String getMessage() {  
  9.             return detailMessage;  
  10.         }  
  11.     }  

2:toString():获取异常类名和异常信息,返回字符串。

3:printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

(4)处理异常处理方式:

       A:try...catch...finally

       格式:

           try{

                需要检测的代码;

           }

            catch(异常类  变量){

                异常处理代码;

           }

           ...

           finally{

                一定会执行的代码;

                   

           }

        可以有下面三种搭配形式:

            **try...catch(...)

            **try...finally

            **try...catch(...)...finally

 

*(final finalize finally三者的区别

     * finally最终的

     * 一定会执行的代码放在这里

     * finally只有一种情况不执行,就是在他之前退出了jvm虚拟机).

[java] view plaincopy
  1. public static void main(String[] args) {  
  2.         //demo1();  
  3.         int num = getNum();  
  4.         System.out.println(num);  
  5.     }  
  6.   
  7.     private static void demo1() {  
  8.         try {  
  9.             System.out.println(1/0);  
  10.         } catch (Exception e) {  
  11.             System.out.println("catch执行了吗");  
  12.             System.exit(0);  
  13.             return;  
  14.         } finally {                                 //关闭流对象,释放资源  
  15.             System.out.println("finally执行了吗");  
  16.         }  
  17.     }  
  18.       
  19.     public static int getNum() {  
  20.         int x = 10;  
  21.         try {  
  22.             System.out.println(1/0);  
  23.             return x;  
  24.         } catch (Exception e) {  
  25.             x = 20;  
  26.             return x;                           //当程序执行到了return语句会有一个返回路径  
  27.         }finally {                              //但是在完全return之前会看有没有finally如果有  
  28.                                                 //先执行finally,再把return返回路径的值返回  
  29.             x = 30;  
  30.             System.out.println("finally执行了吗");  
  31.             //return x;  
  32.         }  
  33.     }  

B:抛出 throws throw

        throws:用于标识函数暴露出的异常。thorws用在函数上,后面跟异常类名(可以由多个,隔开)。

 

        throw:用于抛出异常对象。throw用在函数内,后面跟异常对象。new Exception();

 C:到底用谁?

            **你能处理,建议处理。try...catch...finally

            **你处理不了,抛出。

            **在实际开发中,是分层开发,底层代码是能抛出尽量抛出,用日志记录住异常信息,并提供解决方案

 D:自定义异常

            自定义类继承Exception或者其子类(RuntimeException)


 

[java] view plaincopy
  1. class MyException extends Exception{  
  2.                 MyException(){}  
  3.   
  4.                 MyException(String message){  
  5.                     super(message); //将信息传递给父类,调用父类封装好的构造方法  
  6.                 }  
  7.             }  
  8.   
  9.             class Student {  
  10.                 public void giveAge(int age) throws MyException {  
  11.                     if(age>40 || age<16) {  
  12.                         //throw new MyExcetpion("建议不学了");  
  13.                         MyExcepiont my = new MyExcetpion("建议不学了");  
  14.                         throw my;  
  15.                     }  
  16.                     else {  
  17.                         System.out.println("可以学习Java");  
  18.                     }  
  19.                 }  
  20.             }  

E:RuntimeException和Exception

            区别:RuntimeException就是要你改代码的。你可以不处理。

二.File

    1.什么是File类

        File类对象可以代表一个路径, 此路径可以是文件也可以是文件夹, 该类方法可以对这个路径进行各种操作

    2.创建对象

        给File类构造函数传一个String类型的路径就可以创建对象

        路径分为两种: 绝对路径, 相对路径

            绝对路径: 从盘符开始, 是一个固定的路径

相对路径: 不从盘符开始, 相对于某个位置. 在Eclipse中的Java工程如果使用相对路径, 那么就相对于工程根目录. cmd则相对应于当前目录.

[java] view plaincopy
  1. import java.io.File;  
  2.   
  3. public class Demo1_File {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      * D:\workspace0803\day20\day20笔记.txt 
  8.      */  
  9.     public static void main(String[] args) {  
  10.           
  11.     File file = new File("F:\\2014\\Test3.java");//绝对路径,从盘符开始  
  12.         System.out.println(file.exists());  
  13.           
  14.         File file2 = new File("day20笔记.txt");                   //相对路径,相对于java工程的根目录  
  15.         System.out.println(file1.exists());  
  16.     }  
  17.   
  18. }  

3.常用方法

        *****booleanexists()       判断是否存在

        booleanisAbsolute();     是否是绝对路径

        *****booleanisDirectory(); 是否是文件夹

        *****booleanisFile();      是否是文件

        booleanisHidden();         是否是隐藏

       

        getAbsolutePath();      获取绝对路径

        getFreeSpace();         获取当前盘符剩余空间

        getTotalSpace();        获取当前盘符总空间

        getUsableSpace();       获取当前盘符可用空间

        getParent());      获取父级路径

        getName());        获取文件名

 

        setReadable(false);     设置是否可读

        setWritable(false);     设置是否可写

        setExecutable(false);   设置是否可执行

        canRead();              是否可读

        canWrite();             是否可写

        canExecute();           是否可执行

       

        setLastModified();      设置文件的最后修改时间

        lastModified();    获取文件的最后修改时间     

        createNewFile()    创建文件

        mkdir();          创建文件夹(仅一级)

        mkdirs();          创建文件夹(父级不存在也创建)

       

        renameTo();             改名, 可以移动文件

        delete()          删除, 文件可以直接删除, 文件夹只能删空的

        length()          文件大小

 

4.递归

[java] view plaincopy
  1. public class Demo6_Digui {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      * 递归 
  6.      * 方法自己调用自己 
  7.      * 5的阶乘(5!)
  8.      * fun(5) 
  9.      * 5 * fun(4) 
  10.      *      4 * fun(3) 
  11.      *          3   *  fun(2) 
  12.      *                  2     * fun(1) 
  13.      * 弊端:如果调用的次数过多,会出现栈内存溢出 
  14.      */  
  15.     public static void main(String[] args) {  
  16.         /*int result = 1; 
  17.         for(int i = 1; i <= 5; i++) { 
  18.             result = result * i; 
  19.         } 
  20.          
  21.         System.out.println(result);*/  
  22.         int result = getResult(10000);  
  23.         System.out.println(result);  
  24.     }  
  25.   
  26.     public static int getResult(int num) {  
  27.         if(num == 1) {  
  28.             return 1;  
  29.         }  
  30.           
  31.         return num * getResult(num - 1);  
  32.     }  
  33. }  

举例

     

      键盘录入一个文件夹路径

      如果录入的文件夹路径不存在,提示重输

      如果录入的文件夹路径是文件路径,提示重输

      如果录入的是文件夹路径,将其返回

[java] view plaincopy
  1. import java.io.File;  
  2. import java.util.Scanner;  
  3.   
  4. public class Test1 {  
  5.   
  6.       
  7.     public static void main(String[] args) {  
  8.         File dir = getDir();  
  9.         System.out.println(dir);  
  10.     }  
  11.   
  12.     public static File getDir() {  
  13.         Scanner sc = new Scanner(System.in);                        //创建Scanner  
  14.         System.out.println("请输入一个文件夹路径:");                      //提示  
  15.         while(true) {  
  16.             String line = sc.nextLine();                            //将键盘录入的字符串存储在line中  
  17.             File dir = new File(line);                              //封装成File对象  
  18.             if(!dir.exists()) {                                     //如果路径不存在  
  19.                 System.out.println("您录入的文件夹路径不存在,请重新录入一个文件夹路径");//提示  
  20.             }else if(dir.isFile()) {                                //如果路径是文件  
  21.                 System.out.println("您录入的是文件路径,请重新输入一个文件夹路径");//提示  
  22.             }else {  
  23.                 return dir;                                         //将文件夹路径返回  
  24.             }  
  25.         }  
  26.     }  
  27. }  

三、IO流

    1.概念

        IO流用来处理设备之间的数据传输

        Java对数据的操作是通过流的方式

        Java用于操作流的类都在IO包中

        流按流向分为两种:输入流,输出流。

流按操作类型分为两种:字节流与字符流。  字节流可以操作任何数据,字符流只能操作纯字符数据,比较方便。

    2.IO流常用父类

        字节流的抽象父类:

        InputStream,OutputStream

        字符流的抽象父类:

        Reader, Writer       

    3.IO程序书写

        使用前,导入IO包中的类

        使用时,进行IO异常处理

        使用后,释放资源

 

二.字节流

    1.读取文件

        创建FileInputStream对象, 指定一个文件. 文件必须存在, 不存在则会抛出FileNotFoundException

使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1

        读取结束后需要释放资源, 调用close()方法关闭输入流

    2.写出文件

创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.

        使用write()方法可以向文件写出一个字节.

        写出结束后同样需要调用close()

    3.拷贝文件

        可以从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低

     我们可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出1byte = 8bit

    4.常用方法

        InputStream:字节输入流

            read()          读取一个字节

            read(byte[])    读取若干(数组长度)字节

            available()     获取可读的字节数

            close()         关闭流, 释放资源

        OutputStream:字节输出流

            write(int)      写出一个字节

            write(byte[])   写出数组中的所有字节

            write(byte[],start,len);

            close()         关闭流, 释放资源

5.BufferedInputStream:高效字节输入流

        BufferedInputStream内置了一个缓冲区(数组)

        从BufferedInputStream中读取一个字节时

BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个

        程序再次读取时, 就不用找文件了, 直接从缓冲区中获取

        直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个

6.BufferedOutputStream:高效字节输出流

        BufferedOutputStream也内置了一个缓冲区(数组)

        程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中

    直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里

 

(read()方法每次读取都返回一个字节,为什么用int接收而不用byte接收呢?

因为文件都有结束标记,结束标记都是-1,-1是int类型的,如果结束标记是byte类型的-1,读到文件的中间很有可能遇到11111111.这样文件就会读取终止,剩下读不出来了,所有每次读取返回的都是int,将byte提升为int会在前面补上24个0,byte类型的-1就变成了int类型的255了,这样只有遇到文件的结束标记才会停止读取)

 

 

7.种字节读写方式

       1)根据文件大小创建字节数组,一次读到字节数组中,一次将字节数组中的内容写出去, 这种拷贝的弊端,有可能内存溢出。

 

 

       2)一个字节一个读写,效率慢。

       3)创建字节数组长度为1024*8,将数据读到字节数组中,从字节数组中写出去,写到文件上,相对于单字节           效率快。

       4)读一次先将缓冲区读满,再一个一个的返给, 写一次,是先将缓冲区装满,再一起写出,解决溢出,效率

[java] view plaincopy
  1. import java.io.FileInputStream;  
  2. import java.io.FileNotFoundException;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5.   
  6. public class Demo4_Array {  
  7.   
  8.     /** 
  9.      * @param args 
  10.      * @throws IOException  
  11.      */  
  12.     public static void main(String[] args) throws IOException {  
  13.           
  14.           
  15.           
  16.         FileInputStream fis = new FileInputStream("致青春.mp3");       //创建输入流对象,关联致青春.mp3  
  17.         FileOutputStream fos = new FileOutputStream("copy.mp3");    //创建输出流对象,关联copy.mp3  
  18.         byte[] arr = new byte[fis.available()];                     //根据文件大小创建字节数组  
  19.         fis.read(arr);                                              //一次读到字节数组中  
  20.         fos.write(arr);                                             //一次将字节数组中的内容写出去  
  21.           
  22.         fis.close();  
  23.         fos.close();  
  24.         //这种拷贝的弊端,有可能内存溢出  
  25.     }  
  26. public static void Demo1 throws IOException {  
  27.           
  28.         FileInputStream fis = new FileInputStream("致青春.mp3");  
  29.         FileOutputStream fos = new FileOutputStream("copy.mp3");  
  30.           
  31.         int b;  
  32.         while((b = fis.read()) != -1) {  
  33.             fos.write(b);  
  34.         }  
  35.           
  36.         fis.close();  
  37.         fos.close();  
  38. }  
  39.   
  40.     private static void demo2() throws FileNotFoundException, IOException {  
  41.         FileInputStream fis = new FileInputStream("致青春.mp3");       //创建输入流对象,关联致青春.mp3  
  42.         FileOutputStream fos = new FileOutputStream("copy.mp3");    //创建输出流对象,关联copy.mp3  
  43.         byte[] arr = new byte[1024 * 8];                            //创建字节数组长度为1024*8  
  44.         int len;  
  45.         while((len = fis.read(arr)) != -1) {                        //将数据读到字节数组中  
  46.             fos.write(arr,0,len);                                   //从字节数组中写出去,写到文件上  
  47.         }  
  48.           
  49.         fis.close();                                                //关流,释放资源  
  50.         fos.close();  
  51.     }  
  52.   
  53.   
  54. public static void Demo3 throws IOException {  
  55.         FileInputStream fis = new FileInputStream("致青春.mp3");  
  56.         BufferedInputStream bis = new BufferedInputStream(fis);     //包装输入流  
  57.         FileOutputStream fos = new FileOutputStream("copy.mp3");  
  58.         BufferedOutputStream bos = new BufferedOutputStream(fos);   //包装输出流  
  59.           
  60.         int b;  
  61.         while((b = bis.read()) != -1) {                             //读一次先将缓冲区读满,再一个一个的返给b  
  62.             bos.write(b);                                           //写一次,是先将缓冲区装满,再一起写出  
  63.         }  
  64.           
  65.         bis.close();  
  66.         bos.close();  
  67.     }  
  68. }     

8、字节流读取中文是有弊端的,有可能会读到半个中文

         1,用字符流读

         2,ByteArrayOutputStream

         字节流只写中文,可以写

         但是需要将字符串转换成字节数组写出去

[java] view plaincopy
  1. public class Demo6_Chinese {  
  2.   
  3.       
  4.     public static void main(String[] args) throws IOException {  
  5.         //demo1();  
  6.       
  7.         FileOutputStream fos = new FileOutputStream("bbb.txt");  
  8.         fos.write("还能一起愉快的玩耍吗?".getBytes());  
  9.         fos.close();  
  10.     }  
  11. private static void demo1() throws FileNotFoundException, IOException {  
  12.         FileInputStream fis = new FileInputStream("aaa.txt");  
  13.         int b;  
  14.         while((b = fis.read()) != -1) {                         //读取的是半个中文  
  15.             System.out.println(b);                              //打印的是半个中文  
  16.         }  
  17.         fis.close();  
  18.     }  
  19.   
  20. }  

9、标准的异常处理代码

[java] view plaincopy
  1. import java.io.FileInputStream;  
  2. import java.io.FileNotFoundException;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5.   
  6. public class Demo7_TryFinally {  
  7.   
  8.     /** 
  9.      * @param args 
  10.      * 标准的异常处理代码 
  11.      * @throws IOException  
  12.      * @throws IOException  
  13.      */  
  14.     public static void main(String[] args) throws IOException {  
  15.         //1.7版本的处理异常  
  16.         try(  
  17.             FileInputStream fis = new FileInputStream("aaa.txt");  
  18.             FileOutputStream fos = new FileOutputStream("bbb.txt");  
  19.             MyClose mc = new MyClose();  
  20.         ){  
  21.             int b;  
  22.             while((b = fis.read()) != -1) {  
  23.                 fos.write(b);  
  24.             }  
  25.         }  
  26.     }  
  27.     //1.7版本之前的标准处理异常  
  28.     private static void demo1() throws FileNotFoundException, IOException {  
  29.         FileInputStream fis = null;  
  30.         FileOutputStream fos = null;  
  31.         try {  
  32.             fis = new FileInputStream("aaa.txt");  
  33.             fos = new FileOutputStream("bbb.txt");  
  34.               
  35.             int b;  
  36.             while((b = fis.read()) != -1) {  
  37.                 fos.write(b);  
  38.             }  
  39.         } finally {  
  40.             try{  
  41.                 if(fis != null)  
  42.                     fis.close();  
  43.             }finally {  
  44.                 if(fos != null)  
  45.                     fos.close();  
  46.             }  
  47.         }  
  48.     }  
  49.   
  50. }  
  51.   
  52.   
  53. class MyClose implements AutoCloseable {  
  54.   
  55.     @Override  
  56.     public void close() {  
  57.         System.out.println("我关了");  
  58.     }  
  59.       
  60. }  










0 0
原创粉丝点击