当前位置:   article > 正文

JavaSE 面向对象程序设计进阶 IO流 字节流详解 抛出异常

JavaSE 面向对象程序设计进阶 IO流 字节流详解 抛出异常

input output 像水流一样读取数据

存储和读取数据的解决方案

内存中数据不能永久化存储 程序停止运行 数据消失

File只能对文件本身进行操作 不能读写文件里存储的数据

读写数据必须要有IO流

可以把程序中的数据保存到文件当中

还可以把本地文件中的数据读取到数据当中

分类

流的方向

输入流 读取

输出流 写出

操作文件类型

字节流 操作所有类型的文件

字符流 只能操作纯文本文件

纯文本文件时用微软自带的记事本打开能读的懂的文件

基本用法

写一段文字到本地文件当中

需要把文件放到包下 先创建文件

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. public class Main {
  4. public static void main(String[] args) throws IOException {//抛出异常
  5. //本地文件
  6. FileOutputStream fos=new FileOutputStream("untitled1\\a.txt");
  7. fos.write(97);//父类异常
  8. fos.close();//释放资源
  9. }
  10. }

创建对象时 会根据路径让程序和文件产生通道

之后我们即可以进行数据的传输

当使用了close方法后 相当于切断了通道

写出数据的细节

创建字节输出流对象

1.参数是字符串表示的路径或者是File对象都是可以的

2.如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的

3.如果文件已经存在,则会清空文件

写数据

1.write 方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符

97 -> a

100 -> d

释放资源

是IO流中每一种流都要使用

每一次使用完流后,都要释放IO流

如果不释放流

会显示,操作无法完成,文件已经在Java Platform SE binary中打开

释放资源就是解决了资源的占用

总结

字节输出流FileOutputStream

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. Scanner sc=new Scanner(System.in);
  7. FileOutputStream f=new FileOutputStream("untitled1\\a.txt");
  8. byte arr[]=new byte[]{97,98,99};
  9. f.write(arr,1,2);
  10. f.close();
  11. //文件中是bc
  12. }
  13. }

写出数据的几个问题

1.把字符串写入文件

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. Scanner sc=new Scanner(System.in);
  7. FileOutputStream f=new FileOutputStream("untitled1\\a.txt");
  8. String str="Dduo";
  9. String s=new String("Dduo");
  10. byte[] bytes = str.getBytes();
  11. //把字符串获取成字节数组
  12. f.write(bytes);
  13. f.close();
  14. }
  15. }

window系统

\r 表示回车

\n 表示换行

Linux系统

\n换行

Mac系统

\r换行

在window操作系统中,java对换行进行了优化,虽然完整的是\r\n,但是我们写其中一个\r或者\n

java也可以实现换行,因为java在底层会进行补全

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. Scanner sc=new Scanner(System.in);
  7. FileOutputStream f=new FileOutputStream("untitled1\\a.txt");
  8. String s1=new String("Dduo");
  9. byte[] bytes1 = s1.getBytes();
  10. f.write(bytes1);
  11. String s2=new String("\r\n");
  12. byte[] bytes2 = s2.getBytes();
  13. f.write(bytes2);
  14. String s3=new String("666");
  15. byte[] bytes3 = s3.getBytes();
  16. f.write(bytes3);
  17. f.close();
  18. }
  19. }

创建对象时第二个参数就是续写开关

默认数值是false 表示关闭续写 此时创建对象会清空文件

手动传递true表示打开续写,此时创建对象的时候不会清空文件

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. Scanner sc=new Scanner(System.in);
  7. while(true){
  8. FileOutputStream f=new FileOutputStream("untitled1\\a.txt",true);
  9. String s1=new String("Dduo666");
  10. byte[] bytes1 = s1.getBytes();
  11. f.write(bytes1);
  12. String s2=new String("\r\n");
  13. byte[] bytes2 = s2.getBytes();
  14. f.write(bytes2);
  15. f.close();
  16. }
  17. }
  18. }

这样会输出44万行 直到文本文档的大小达到2.56MB

小结

字节输入流FileInputStream

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. Scanner sc=new Scanner(System.in);
  8. //创建对象
  9. FileInputStream fis=new FileInputStream("untitled1\\a.txt");
  10. //读取数据
  11. int b1 = fis.read();
  12. System.out.println((char) b1);
  13. fis.close();
  14. }
  15. }

read方法负责读取文件当中的数据

如果读不到了 返回-1

写入数据的细节

如果文件不存在就会直接报错

Java为什么会这么设计呢

输出流:不存在,创建

输入流:不存在,报错 因为创建出来的数据是没有数据的没有任何意义 这种逻辑没有意义

读取数据

一次读一个字节

读出来的数据是在ASCII上对应的数字

读到文件末尾了,read方法返回的是-1

如果是空格 则读取空格所对应的ASCII码30

如果是负数 则会先读取符号 不会当做一个整体

释放资源

每一次使用完流必须要释放资源

字节输入流循环读取

  1. import java.io.FileInputStream;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. Scanner sc=new Scanner(System.in);
  7. //创建对象
  8. FileInputStream fis=new FileInputStream("untitled1\\a.txt");
  9. int b;
  10. while((b=fis.read())!=-1) System.out.print((char) b);
  11. }
  12. }

定义一个变量b

read方法表示读取数据。并且读取一次就移动一次指针

和迭代器相似

所以要用第三方变量接收

文件拷贝 (挨个字节拷贝)

拷贝文件夹到指定的文件当中

先开的流最后关闭

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. Scanner sc=new Scanner(System.in);
  8. long start=System.currentTimeMillis();
  9. //写入
  10. FileOutputStream fos=new FileOutputStream("untitled1\\a.txt");
  11. //读取
  12. FileInputStream fis=new FileInputStream("untitled1\\b.txt");
  13. int b;
  14. while((b=fis.read())!=-1) fos.write(b);
  15. long end=System.currentTimeMillis();//获取当前系统的时间
  16. System.out.println("运行时间为:"+(end-start));
  17. //先开的流最后关
  18. fis.close();
  19. fos.close();
  20. }
  21. }

FileInputStream读取的问题

拷贝一次只能读写一个字节

速度太慢了

可以用字节数组

一次读一个字节数组的数据,我们要尽可能将字节数组填满

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. Scanner sc=new Scanner(System.in);
  8. long start=System.currentTimeMillis();
  9. //读取
  10. FileInputStream fis=new FileInputStream("untitled1\\b.txt");
  11. //创建字节数组
  12. byte []bytes=new byte[7];
  13. System.out.println(fis.read(bytes));
  14. System.out.println(new String(bytes));
  15. long end=System.currentTimeMillis();
  16. System.out.println("运行时间为:"+(end-start)+"毫秒");
  17. //先开的流最后关
  18. fis.close();
  19. }
  20. }

输出结果是7个字节

其中换行回车一共是2个字节 一个英文字母是一个字节

如果越界了 读取不到东西 数组元素就不会改变

read方法如果读取不到数据就会返回-1

文件拷贝代码改写

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. Scanner sc=new Scanner(System.in);
  8. long start=System.currentTimeMillis();
  9. //写入
  10. FileOutputStream fos=new FileOutputStream("untitled1\\a.txt");
  11. //读取
  12. FileInputStream fis=new FileInputStream("untitled1\\b.txt");
  13. int b;
  14. byte []bytes=new byte[1024*1024*5];
  15. while((b=fis.read(bytes))!=-1) fos.write(bytes,0, b);
  16. long end=System.currentTimeMillis();//获取当前系统的时间
  17. System.out.println("拷贝成功");
  18. System.out.println("运行时间为:"+(end-start));
  19. //先开的流最后关
  20. fis.close();
  21. fos.close();
  22. }
  23. }

后两个参数是防止读取不到东西导致把上一次存入字节数组的数据又写入文件

try...catch异常处理

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. Scanner sc=new Scanner(System.in);
  8. long start=System.currentTimeMillis();//获取当前系统的时间
  9. FileOutputStream fos=null;
  10. FileInputStream fis=null;
  11. try {
  12. //写入
  13. fos=new FileOutputStream("untitled1\\a.txt");
  14. //读取
  15. fis=new FileInputStream("untitled1\\b.txt");
  16. int b;
  17. byte []bytes=new byte[1024*1024*5];
  18. while((b=fis.read(bytes))!=-1) fos.write(bytes,0, b);
  19. long end=System.currentTimeMillis();//获取当前系统的时间
  20. System.out.println("拷贝成功");
  21. System.out.println("运行时间为:"+(end-start)+"毫秒");
  22. }
  23. catch (IOException e) {
  24. throw new RuntimeException(e);
  25. }
  26. finally {
  27. if(fos!=null) {
  28. try {
  29. fis.close();
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. if(fis!=null)
  35. try {
  36. fis.close();
  37. } catch (IOException e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. //先开的流最后关
  42. }
  43. }

代码复杂

我们需要学习一下设计思想

释放资源过于复杂

AutoCloseable接口

以后所有的异常我们都是抛出处理

个人号推广

博客主页

朱道阳-CSDN博客

Web后端开发

https://blog.csdn.net/qq_30500575/category_12624592.html?spm=1001.2014.3001.5482

Web前端开发

https://blog.csdn.net/qq_30500575/category_12642989.html?spm=1001.2014.3001.5482

数据库开发

https://blog.csdn.net/qq_30500575/category_12651993.html?spm=1001.2014.3001.5482

项目实战

https://blog.csdn.net/qq_30500575/category_12699801.html?spm=1001.2014.3001.5482

算法与数据结构

https://blog.csdn.net/qq_30500575/category_12630954.html?spm=1001.2014.3001.5482

计算机基础

https://blog.csdn.net/qq_30500575/category_12701605.html?spm=1001.2014.3001.5482

回忆录

https://blog.csdn.net/qq_30500575/category_12620276.html?spm=1001.2014.3001.5482

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/817045
推荐阅读
相关标签
  

闽ICP备14008679号