java IO流

打印 上一主题 下一主题

主题 927|帖子 927|积分 2781

Java IO流

什么是流?

概念:内存和存储设备之间传输数据的通道。
数据借助流传输。
流分类:

  • 按照方向:输入流(将存储设备中的内容读入到内存中)和输出流(将内存中的内容写入到存储设备中)
  • 按照单位:字节流(以字节为单位,可以读写所有数据)和字符流(以字符为单位,只能读取文本数据)
  • 按照功能:节点流(具有实际传输数据的读写功能)和过滤流(在节点流的基础之上增强功能)
字节流

字节流的父类(抽象类):

  • InputStream:字节输入流:提供一些如read(),close()的方法
  • OutputStream:字节输出流:提供一些如write(),close()的方法

文件字节流


  • FileInputStream:文件字节输入流,继承字节输入流
  • FileOutputStream:文件字节输出流,继承字节输入流

文件字节输入流操作:
  1. //创建FileInputStream并且指定文件路径
  2. FileInputStream fis = new FileInputStream("d:\\aa.txt");
  3. int data = 0;
  4. //read返回的int,当等于-1表示读完了,如果是字符返回对应的asc码
  5. //一次读取一个字节
  6. while ((data=fis.read())!=-1){
  7.     System.out.println((char) data);
  8. }
  9. /*
  10. a
  11. b
  12. c
复制代码
什么为一次读取一个字节的情况
当需要一次读取多个字节
  1. //创建FileInputStream并且指定文件路径
  2. FileInputStream fis = new FileInputStream("d:\\aa.txt");
  3. //一次读取多个个字节
  4. byte[] buf = new byte[3];
  5. //本处read返回实际读取个数,读完返回-1,并且将读取到的存储在buf中
  6. //因为数组大小一次读取三个
  7. System.out.println(fis.read(buf));
  8. System.out.println(new String(buf));
  9. fis.close();
  10. /*
  11. 3
  12. abc
  13. */
  14. //或者
  15. FileInputStream fis = new FileInputStream("d:\\aa.txt");
  16.         byte[] buf = new byte[3];
  17.         int count=0;
  18.         while ((count=fis.read(buf))!=-1){
  19.          System.out.println(new String(buf,0,count));
  20.         }
  21.         fis.close();
  22. /*
  23. abc
  24. def
  25. g
复制代码
本处只是例子,实际操作时缓冲区数组不需要创建得太小,可以是1024以上
文件字节输出流操作:
  1. //创建文件字节输出流,为true代表文件已经存在时追加,false每次都会覆盖(默认)
  2. FileOutputStream fos=new FileOutputStream("d://aa.txt",false);
  3. fos.write(97);
  4. fos.write('b');
  5. fos.write('c');
  6. //文件中:abc
  7. //要写入字符串:转成byte数组
  8. String s = "helloworld";
  9. fos.write(s.getBytes());
  10. //文件中:abchelloworld
复制代码
实现复制操作:
  1. FileInputStream fis = new FileInputStream("d:\\aa.txt");
  2. FileOutputStream fos = new FileOutputStream("d:\\bb.txt");
  3. byte[] buf = new byte[1024];
  4. int count=0;
  5. while ((count=fis.read(buf))!=-1){
  6.     fos.write(buf,0,count);
  7. }
  8. fis.close();
  9. fos.close();
复制代码
字节缓冲流


  • 缓冲流:BufferedInputStream/BufferedOutputStream
  • 继承了过滤流(FilterOutputStream/FilterInputStream),而过滤流又继承了文件字节流
  • 内置了缓存区(8k)
  • 作用:提高IO效率,减少访问磁盘次数;数据存储在缓存区,flush是将缓冲区的内容写入文件中,也可以直接close,后面实现缓冲区的类类似
字节输入缓冲流:
  1. //        创建BufferedInputStream,需要传入一个底层流
  2.         FileInputStream fis = new FileInputStream("d:\\aa.txt");
  3.         BufferedInputStream bis = new BufferedInputStream(fis);
  4. //        读取:类似,但是这个有缓冲区效率更高
  5.         int data = 0;
  6.         while ((data=bis.read())!=-1){
  7.             System.out.print((char)data);
  8.         }
  9.         //当然也可以和文件字节流一样,直接再创建一个缓冲区实现,一模一样但是因为内部缓冲区的存在效率更高
  10.         
  11. //        关闭这一个就行
  12.         bis.close();
  13. //out:abchelloworld
复制代码
字节输出缓冲流:
  1. FileOutputStream fos = new FileOutputStream("d://bb.txt");
  2. BufferedOutputStream bos = new BufferedOutputStream(fos);
  3. //转义符如换行等也可以写入也可以
  4. String s = "hello\r\n";
  5. bos.write(s.getBytes());//这是写入了缓冲区,没有写入文件
  6. bos.flush();//需要刷新才能从缓冲区真正写入文件
  7. bos.close();//当然close时自动flush
复制代码
对象流


  • 对象流:ObjectOutputStream/ObjectInputStream
  • 可以实现写入或者读取对象
  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串的功能,不只是能读写int和byte
  • readObject()从流中读取一个对象;writeObject(Object obj)向流中写入一个对象
  • 使用流传输对象的过程被称为序列化(写入)和反序列化(读取)
  • 继承文件字节流,需要基于其才能创建
  • 序列化和反序列化的对象类都必须实现Serializable接口(该接口本身没有任何方法仅仅标志该类可以序列化),而且其中关联的其他类也要实现该接口
  • 可以在类中自定义生成常量private static final long serialVersionUID ,该常量为序列化版本号用来标识该类,即使是同一个类如果UID不同依旧被认为不是同一个类无法反序列化不同UID的类
  • 使用transient修饰实现,表示该属性不需要序列化(例如:private transient int age )
  • 静态属性不能序列化
序列化:
  1. public class  Student  implements Serializable {}
  2. //main:
  3. FileOutputStream fos = new FileOutputStream("d://aa.txt");
  4.         ObjectOutputStream oos = new ObjectOutputStream(fos);
  5. //        序列化
  6.         Student student = new Student();
  7.         oos.writeObject(student);
  8. //        oos.writeBoolean();写入boolean
  9. //         oos.writeBytes("hellow");//写入字符串
  10. //        其他基本类型也有相应的办法写入
  11.         oos.close();
复制代码
反序列化:
  1. FileInputStream fis = new FileInputStream("d://aa.txt");
  2. ObjectInputStream ois = new ObjectInputStream(fis);
  3. //读取存入的第一个对象
  4. Student s = (Student)ois.readObject();
  5. ois.close();
复制代码
序列化、反序列化多个对象时可以使用集合:
  1. //序列化
  2. FileOutputStream fos = new FileOutputStream("d://aa.txt");
  3.         ObjectOutputStream oos = new ObjectOutputStream(fos);
  4. //        序列化
  5.         Student student = new Student();
  6.         Student student1 = new Student();
  7.         ArrayList<Student> arrayList = new ArrayList<>();
  8.         arrayList.add(student);
  9.         arrayList.add(student1);
  10.         oos.writeObject(arrayList);
  11.         oos.close();
  12. //反序列化
  13. FileInputStream fis = new FileInputStream("d://aa.txt");
  14.         ObjectInputStream ois = new ObjectInputStream(fis);
  15.         ArrayList<Student> arrayList = (ArrayList<Student>) ois.readObject();
  16.         ois.close();
复制代码
常见字符编码


字符流

问题的引出:
  1. FileInputStream fis = new FileInputStream("d://aa.txt");
  2. int data = 0;
  3. while ((data=fis.read())!=-1){
  4.     System.out.println((char)data);
  5. }
  6. fis.close();
  7. //上述代码当我们读取的文件中为中文时得到乱码。
  8. //原因:我们是运用字节流一个一个字节读取文件,而本处的文件编码方式是utf-8(中文常见的编码方式),每个中文字占3个字节。当一个一个字节读取时出现乱码
复制代码
这种情况下我们需要字符流
字符流的父类(抽象类):
Reader(字符输入流)和Writer(字符输出流)
只能用于文本文件

文件字符流


  • FileReader和FileWriter
  • 父类是InputStreamReader和OutputStreamWriter,而这两者的父类又是Reader和Writer
  • 采用默认字符编码

FileReader:
  1. FileReader fr = new FileReader("d://aa.txt");
  2.        //单个字符的读取
  3. //        int data = 0;
  4. //        while ((data=fr.read())!=-1){//读取一个字符
  5. //            System.out.println((char)data);
  6. //        }
  7. //创建缓冲区读取
  8. //缓冲区为2字符
  9.         char[] buf = new char[2];
  10.         int count = 0;
  11.         while ((count = fr.read(buf))!=-1){
  12.             System.out.println(new String(buf,0,count));
  13.         }
  14.         fr.close();
  15. /*out:
  16. 你好
复制代码
FileWriter:
  1. FileWriter fw = new FileWriter("d://aa.txt");
  2. fw.write("你好吗");
  3. fw.flush();
  4. fw.close();
复制代码
字符缓冲流


  • 缓冲流:BufferedReader/BufferedWriter
  • 高效读写
  • 支持输入换行符
  • 可以一次写一行、读一行
  • 可以指定缓冲区大小,也可以默认(8K)
  • 新建需要基础字符流(文件字符流)
  • 继承Reader和Writer
读取:
  1. FileReader fr = new FileReader("d://aa.txt");
  2.        BufferedReader br = new BufferedReader(fr);
  3. //        和上面其他类类似的方法不再重写
  4. //        特有的:读一行,末尾返回null
  5.         String s = null;
  6.         //一行一行的读取
  7.         while ((s=br.readLine())!=null){
  8.             System.out.println(s);
  9.         }
  10.         br.close();
  11. //out:你好呀
复制代码
写入:
  1.       FileWriter fw = new FileWriter("d:\\aa.txt");
  2.       BufferedWriter bw = new BufferedWriter(fw);
  3. //      写入
  4.         bw.write("好好学习");
  5. //        写入一个换行windows:\r\n linux:\n
  6.         bw.newLine();
  7.         bw.write(",天天向上");
  8.         bw.close();
  9. /*文件:
  10. 好好学习
  11. ,天天向上
复制代码
打印流


  • PrintWriter:

    • 支持print()/println(),支持写入后换行
    • 支持数据原样打印
    • 继承Writer类
    • 类似PrintStream,但是PrintWriter只能打印字符流,而PrintStream可以打印字节流
    1. PrintWriter pw = new PrintWriter("d://aa.txt");
    2. //      打印并且换行
    3.         pw.println(97);
    4.         pw.println(true);
    5. //打印
    6.         pw.print("a");
    7.                 pw.print("b");
    8.         pw.close();
    9. /*文件中:
    10. 97
    11. true
    12. ab
    复制代码
转换流


  • 也叫桥转换流:InputStreamReader/OutputStreamWriter
  • 可以将字节流转换为字符流
  • 可设置字符的编码方式
  • 继承字符流Reader/Writer
  • 创建时需要基本的文件字符流
InputStreamReader:
  1. FileInputStream fis = new FileInputStream("d://aa.txt");
  2. InputStreamReader isr = new InputStreamReader(fis,"utf-8");
  3. int data=0;
  4. //一个一个字符读取
  5. while ((data=isr.read())!=-1){
  6.     System.out.print((char)data);
  7. }
  8. isr.close();
复制代码
OutputStreamWriter:
  1. FileOutputStream fos = new FileOutputStream("d://aa.txt");
  2. OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
  3. for(int i=0;i<10;i++){
  4.     osw.write("我爱中国\r\n");
  5.     osw.flush();
  6. }
  7. osw.close();
复制代码
Prorerties


  • 属性集合
  • 特点:

  • 存储属性名和属性值
  • 属性名和属性值都是字符串类型
  • 没有泛型
  • 继承Hashtable集合,具体看集合那一章笔记
  • 和流有关
  1. //        分隔符
  2.         System.out.println("路径分割符"+File.pathSeparator);
  3.         System.out.println("名字分割符"+File.separator);
  4.         File file = new File("d://cc.txt");
  5. //        判断文件是否存在
  6.         if(!file.exists()){
  7. //            创建文件
  8.             boolean b = file.createNewFile();
  9.             System.out.println("创建结果:"+b);
  10.         }
  11.        if(file.exists()) {
  12. //           直接删除
  13.            System.out.println("删除结果" + file.delete());
  14.            //使用jvm退出时删除
  15.            file.deleteOnExit();
  16.        }
  17. //       获取文件信息
  18.         System.out.println("绝对路径"+file.getAbsolutePath());
  19.        //看你创建时传入的路径
  20.         System.out.println("获取路径"+file.getPath());
  21. //        获取名称
  22.         System.out.println("获取名称"+file.getName());
  23. //        获取父目录
  24.         System.out.println("获取父目录"+file.getParent());
  25. //        获取文件长度
  26.         System.out.println("获取文件长度"+file.length());
  27. //        文件创建时间
  28.         System.out.println("文件创建时间"+new Date(file.lastModified()).toString());
  29. //        判断文件是否可写
  30.         System.out.println("是否可写"+file.canWrite());
  31. //        是否是文件
  32.         System.out.println("是否是文件"+file.isFile());
  33. //        是否隐藏
  34.         System.out.println("是否隐藏"+file.isHidden());
  35. /*
  36. 路径分割符;
  37. 名字分割符\
  38. 创建结果:true
  39. 删除结果true
  40. 绝对路径d:\cc.txt
  41. 获取路径d:\cc.txt
  42. 获取名称cc.txt
  43. 获取父目录d:\
  44. 获取文件长度0
  45. 文件创建时间Thu Jan 01 08:00:00 CST 1970
  46. 是否可写false
  47. 是否是文件false
  48. 是否隐藏false
复制代码
  1. File dir = new File("d://cc/aa");
  2. //        判断文件是否存在
  3.         if(!dir.exists()){
  4. //            创建文件夹:只能创建单集目录
  5. //            boolean b = dir.mkdir();
  6. //            创建多级目录
  7.             boolean b = dir.mkdirs();
  8.             System.out.println("创建结果:"+b);
  9.         }
  10.        if(dir.exists()) {
  11. //           直接删除:最下层且必须为空目录
  12.            System.out.println("删除结果" + dir.delete());
  13.            //使用jvm退出时删除,休眠结束后删除
  14.            dir.deleteOnExit();
  15.            Thread.sleep(5000);
  16.        }
  17. //       获取文件信息
  18.         System.out.println("绝对路径"+dir.getAbsolutePath());
  19.        //看你创建时传入的路径
  20.         System.out.println("获取路径"+dir.getPath());
  21. //        获取名称
  22.         System.out.println("获取名称"+dir.getName());
  23. //        获取父目录
  24.         System.out.println("获取父目录"+dir.getParent());
  25. //        文件创建时间
  26.         System.out.println("文件创建时间"+new Date(dir.lastModified()).toString());
  27. //        判断是否是文件夹
  28.         System.out.println("是否可写"+dir.isDirectory());
  29. //        是否隐藏
  30.         System.out.println("是否隐藏"+dir.isHidden());
  31. //        遍历文件夹
  32.         String[] file = dir.list();
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表