欢迎光临,了解微信小程序开发,就上易用通!

【后端】java基础(5.7)java高级基础之IO与异常处理

发布:2018-01-24 15:35浏览: 来源:网络 作者:tianshu

前面讲了那么多,都是对java数据的操作,本章来讲讲对文件的操作——IO流。
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
我们的IO总的来说可以分两种,一种是只能处理纯字符文件的,叫做字符流,另一种是能处理所有类型的叫做字节流,在每种下,我们又可以分为读取和输出两种操作。

  • 字符流操作:
    • Reader 读取
    • Writer 输出
  • 字节流操作:
    • InputStream 读取
    • OutputStream 输出

我们来尝试读取字符流文件:
首先我们在电脑f盘根目录(当然,你随便在哪都行)建一个txt文本文件,里面写上内容:
【后端】java基础(5.7)java高级基础之IO与异常处理(图1)
然后写上代码:


  1. public static void main(String[] args) throws IOException {
  2. Reader reader=new FileReader("F://Test.txt");//获取文件
  3. int i=reader.read();
  4. System.out.println(i);
  5. System.out.println((char)i);//read()方法读取第一个字符“i”
  6. i=reader.read();
  7. System.out.println((char)i);//read()方法读取第一个字符“ ”(空格)
  8.  
  9. i=reader.read();
  10. System.out.println((char)i);//read()方法读取第一个字符“a”
  11.  
  12. i=reader.read();
  13. System.out.println((char)i);//read()方法读取第一个字符“m”
  14.  
  15. reader.close(); //不想读了,关闭reader
  16. }

运行的结果为: 【后端】java基础(5.7)java高级基础之IO与异常处理(图2) 以上是Reader读取文件的方式,要一个个字符的读,效率非常慢,但是由上述代码我们可以看出,我们反复在用reader.read()给i这这个变量赋值,然后i打印出来的是我们流中相对应的Unicode码,因此用char强转之后就能变成相对应的字符(可以参考前面的基本类型与变量的char)。还有一点可以看出,我们的流读过一次就没了(被消耗了),这个流就好比你水管里的水一样,流过来你用了就没了,再流进来的就是新的了。 一个个字节的度读太累,因此我们可以用循环来读取整段话:


  1. public static void main(String[] args) throws IOException {
  2. Reader reader=new FileReader("F://Test.txt");//获取文件
  3. int i=0;
  4.  
  5. while((i=reader.read())!=-1){//每次重新赋值,并且判断是否读完(等于-1即读完了)
  6. System.out.println((char)i);
  7. if(i==-1)
  8. break;
  9. }
  10. reader.close();
  11. }

读出来的结果是: 【后端】java基础(5.7)java高级基础之IO与异常处理(图3) 我们再来看看往txt文件内写入内容:


  1. public static void main(String[] args) throws IOException {
  2. Writer writer = new FileWriter("F://Test.txt");//获取文件路径
  3.  
  4. writer.write("我是 JAVA IO");//写入内容
  5. writer.close();//关闭Writer
  6. }

这段代码运行之后控制台并没有什么反应,但是我们重新打开这个文件你会发现内容已经变了: 【后端】java基础(5.7)java高级基础之IO与异常处理(图4)

现在你已经学会最基本的IO的操作了,但是我们的IO操作并不仅仅这么简单,还要考虑很多复杂的问题,比如字符编码问题(不信你可以把第一步中的文字换成中文试试),以及文件是否存在(比如去读取一个并不存在的文件),这些事情我们就用常用的字节流操作来处理: 字节流操作,就是把文件转成字节来进行处理的方法,我们来试试它的读取:


  1. public static void main(String[] args) {
  2. try {//捕获异常
  3. File file=new File("F://Test.txt");//用File获取文件
  4. if(file.isFile() && file.exists()){ //判断文件是否存在(file.isFile()方法判断是否是文件,file.exists()方法判断文件是否存在)
  5. InputStream inputStream = new FileInputStream(file);
  6. byte b[]=new byte[(int)file.length()];//创建合适文件大小的数组(file.length()方法可获取文件内容长度)
  7. inputStream.read(b);//读取文件中的内容到b[]数组
  8. inputStream.close();//关闭InputStream
  9. System.out.println(new String(b));
  10. }else{
  11. System.out.println("找不到指定的文件");
  12. }
  13. } catch (Exception e) {//抛出异常
  14. System.out.println("读取文件内容出错");
  15. e.printStackTrace();
  16. }
  17. }

字节流操作往txt文件内写入内容:


  1. public static void main(String[] args) {
  2. try{
  3. File file = new File("F://Test.txt");//获取文件
  4. if(!file.isFile() && !file.exists()){//判断问是否存在(file.isFile()方法判断是否是文件,file.exists()方法判断文件是否存在),若不存在,则创建一个
  5. file.createNewFile();//创建文件
  6. }
  7. OutputStream outputStream=new FileOutputStream(file);
  8. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");//设置编码为UTF-8
  9. outputStreamWriter.write("这是输出流");
  10. outputStreamWriter.close();// 关闭输出流
  11. } catch (IOException e) {
  12. e.printStackTrace();
  13. }
  14. }

上述代码和之前的代码效果基本差不多,但是他们不仅可以读取txt文件,还可以读取比如照片,视频等别的格式的文件,(有兴趣的话可以试一试把c盘的照片存到d盘去~),输出的代码,大家可以将文件名改成不存在的,你会发现真的就在f盘下创建了这个文件并输出了内容。 IO的应用就这么简单,唯一要注意的两点是:

  • 一定要抛异常或者捕获异常
  • 用完之后必须关闭流(close()方法)

下面来说说什么叫抛异常或者捕获异常: 在上面的代码中,要么是在main方法后面加上了throws IOException,要么是用了try…catch包着代码。这两者都是处理异常的方法:

  • throws是将异常丢给调用它的程序去处理
  • try…catch是自己处理

那么什么是异常呢?

  • 异常(Exception)就是一些已知可能出现的但是避免不了的非逻辑的错误 比如前面讲除法运算时,出现的除数为0的情况,这种情况可以通过编译器通过,但是我们运行的时候下面却报错了,这个错就是jvm抛给我们的,报错了就影响了程序的正常运行,那么,为了不影响程序正常运行,我们需要手动处理一下:
    
    		
    1. public static void main(String[] args) {
    2. int a = 1;
    3. int b = 0;
    4. try {
    5. System.out.println(a/b);
    6. } catch (Exception e) {
    7. System.out.println("除数不能为0");
    8. }
    9. }
    此时我们的运行结果便是: 【后端】java基础(5.7)java高级基础之IO与异常处理(图5) 当然,我们也可以将异常抛给别人处理,比如我们封装个除法方法:
    
    		
    1. public static void main(String[] args) {
    2. try {
    3. division(1, 0);//传入1、0两个参数,1、0为方法中a,b的实参
    4. } catch (Exception e) {
    5. System.out.println("除数不能为0");
    6. }
    7. }
    8. public static int division(int a, int b) throws Exception{//传入参数a、b,a、b为形参,返回值int类型,并且抛出异常
    9. return a/b;
    10. }
    当封装好方法,并且调用了这个方法,我们必须抛异常或者处理异常,否则编译不通过。上面处除了打印错误,我们还可以写别的逻辑代码,但是不管抛还是解决,异常总是存在的,如果一直抛上去,最终抛给jvm虚拟机,那么结果就是jvm虚拟机会将错误原本的呈现。




免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。