黑马程序员 异常处理、File类和IO流之字节读写

------<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 的详细消息字符串

	String detailMessage;
			Throwable(){}

			Throwable(String message) {
				this.detailMessage = message;
			}

			public String getMessage() {
				return detailMessage;
			}
		}

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虚拟机).

public static void main(String[] args) {
		//demo1();
		int num = getNum();
		System.out.println(num);
	}

	private static void demo1() {
		try {
			System.out.println(1/0);
		} catch (Exception e) {
			System.out.println("catch执行了吗");
			System.exit(0);
			return;
		} finally {									//关闭流对象,释放资源
			System.out.println("finally执行了吗");
		}
	}
	
	public static int getNum() {
		int x = 10;
		try {
			System.out.println(1/0);
			return x;
		} catch (Exception e) {
			x = 20;
			return x;							//当程序执行到了return语句会有一个返回路径
		}finally {								//但是在完全return之前会看有没有finally如果有
												//先执行finally,再把return返回路径的值返回
			x = 30;
			System.out.println("finally执行了吗");
			//return x;
		}
	}

B:抛出 throws throw

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

 

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

 C:到底用谁?

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

            **你处理不了,抛出。

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

 D:自定义异常

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


 

class MyException extends Exception{
				MyException(){}

				MyException(String message){
					super(message); //将信息传递给父类,调用父类封装好的构造方法
				}
			}

			class Student {
				public void giveAge(int age) throws MyException {
					if(age>40 || age<16) {
						//throw new MyExcetpion("建议不学了");
						MyExcepiont my = new MyExcetpion("建议不学了");
						throw my;
					}
					else {
						System.out.println("可以学习Java");
					}
				}
			}

E:RuntimeException和Exception

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

二.File

    1.什么是File类

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

    2.创建对象

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

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

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

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

import java.io.File;

public class Demo1_File {

	/**
	 * @param args
	 * D:\workspace0803\day20\day20笔记.txt
	 */
	public static void main(String[] args) {
		
	File file = new File("F:\\2014\\Test3.java");//绝对路径,从盘符开始
		System.out.println(file.exists());
		
		File file2 = new File("day20笔记.txt");					//相对路径,相对于java工程的根目录
		System.out.println(file1.exists());
	}

}

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()               文件大小

   

        String[]list()

        *****File[]listFiles()  


4.递归

public class Demo6_Digui {

	/**
	 * @param args
	 * 递归
	 * 方法自己调用自己
	 * 5!
	 * fun(5)
	 * 5 * fun(4)
	 * 		4 * fun(3)
	 * 			3   *  fun(2)
	 * 					2     * fun(1)
	 * 弊端:如果调用的次数过多,会出现栈内存溢出
	 */
	public static void main(String[] args) {
		/*int result = 1;
		for(int i = 1; i <= 5; i++) {
			result = result * i;
		}
		
		System.out.println(result);*/
		int result = getResult(10000);
		System.out.println(result);
	}

	public static int getResult(int num) {
		if(num == 1) {
			return 1;
		}
		
		return num * getResult(num - 1);
	}
}

举例

     

      键盘录入一个文件夹路径

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

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

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

import java.io.File;
import java.util.Scanner;

public class Test1 {

	
	public static void main(String[] args) {
		File dir = getDir();
		System.out.println(dir);
	}

	public static File getDir() {
		Scanner sc = new Scanner(System.in);						//创建Scanner
		System.out.println("请输入一个文件夹路径:");						//提示
		while(true) {
			String line = sc.nextLine();							//将键盘录入的字符串存储在line中
			File dir = new File(line);								//封装成File对象
			if(!dir.exists()) {										//如果路径不存在
				System.out.println("您录入的文件夹路径不存在,请重新录入一个文件夹路径");//提示
			}else if(dir.isFile()) {								//如果路径是文件
				System.out.println("您录入的是文件路径,请重新输入一个文件夹路径");//提示
			}else {
				return dir;											//将文件夹路径返回
			}
		}
	}
}

三、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)读一次先将缓冲区读满,再一个一个的返给, 写一次,是先将缓冲区装满,再一起写出,解决溢出,效率

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_Array {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		
		
		
		FileInputStream fis = new FileInputStream("致青春.mp3");		//创建输入流对象,关联致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//创建输出流对象,关联copy.mp3
		byte[] arr = new byte[fis.available()];						//根据文件大小创建字节数组
		fis.read(arr);												//一次读到字节数组中
		fos.write(arr);												//一次将字节数组中的内容写出去
		
		fis.close();
		fos.close();
		//这种拷贝的弊端,有可能内存溢出
	}
public static void Demo1 throws IOException {
		
		FileInputStream fis = new FileInputStream("致青春.mp3");
		FileOutputStream fos = new FileOutputStream("copy.mp3");
		
		int b;
		while((b = fis.read()) != -1) {
			fos.write(b);
		}
		
		fis.close();
		fos.close();
}

	private static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("致青春.mp3");		//创建输入流对象,关联致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//创建输出流对象,关联copy.mp3
		byte[] arr = new byte[1024 * 8];							//创建字节数组长度为1024*8
		int len;
		while((len = fis.read(arr)) != -1) {						//将数据读到字节数组中
			fos.write(arr,0,len);									//从字节数组中写出去,写到文件上
		}
		
		fis.close();												//关流,释放资源
		fos.close();
	}


public static void Demo3 throws IOException {
		FileInputStream fis = new FileInputStream("致青春.mp3");
		BufferedInputStream bis = new BufferedInputStream(fis);		//包装输入流
		FileOutputStream fos = new FileOutputStream("copy.mp3");
		BufferedOutputStream bos = new BufferedOutputStream(fos);	//包装输出流
		
		int b;
		while((b = bis.read()) != -1) {								//读一次先将缓冲区读满,再一个一个的返给b
			bos.write(b);											//写一次,是先将缓冲区装满,再一起写出
		}
		
		bis.close();
		bos.close();
	}
}	

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

         1,用字符流读

         2,ByteArrayOutputStream

         字节流只写中文,可以写

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

public class Demo6_Chinese {

	
	public static void main(String[] args) throws IOException {
		//demo1();
	
		FileOutputStream fos = new FileOutputStream("bbb.txt");
		fos.write("还能一起愉快的玩耍吗?".getBytes());
		fos.close();
	}
private static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("aaa.txt");
		int b;
		while((b = fis.read()) != -1) {							//读取的是半个中文
			System.out.println(b);								//打印的是半个中文
		}
		fis.close();
	}

}

9、标准的异常处理代码

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo7_TryFinally {

	/**
	 * @param args
	 * 标准的异常处理代码
	 * @throws IOException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//1.7版本的处理异常
		try(
			FileInputStream fis = new FileInputStream("aaa.txt");
			FileOutputStream fos = new FileOutputStream("bbb.txt");
			MyClose mc = new MyClose();
		){
			int b;
			while((b = fis.read()) != -1) {
				fos.write(b);
			}
		}
	}
	//1.7版本之前的标准处理异常
	private static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("aaa.txt");
			fos = new FileOutputStream("bbb.txt");
			
			int b;
			while((b = fis.read()) != -1) {
				fos.write(b);
			}
		} finally {
			try{
				if(fis != null)
					fis.close();
			}finally {
				if(fos != null)
					fos.close();
			}
		}
	}

}


class MyClose implements AutoCloseable {

	@Override
	public void close() {
		System.out.println("我关了");
	}
	
}





 





 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值