Java IO学习笔记

举报
江南一点雨 发表于 2021/08/17 00:56:34 2021/08/17
【摘要】 Java流的分类,一般可按以下方式分: 按方向分,分为输入流,输出流。按类型分,分为字节流和字符流。 2.1字节流是通过字节来读取数据 2.2字符流是通过字符来读取数据按操作方式分,分为节点流和过滤流。 3.1 可以直接创建的流称为节点流,比如输入流,输出流 3.2 过滤流可以装饰节点流,让流的功能变得更加强大,过滤流采用装饰者模式,对输入流进行包装。比如说B...

Java流的分类,一般可按以下方式分:

  1. 按方向分,分为输入流,输出流。
  2. 按类型分,分为字节流和字符流。
    2.1字节流是通过字节来读取数据
    2.2字符流是通过字符来读取数据
  3. 按操作方式分,分为节点流和过滤流。
    3.1 可以直接创建的流称为节点流,比如输入流,输出流
    3.2 过滤流可以装饰节点流,让流的功能变得更加强大,过滤流采用装饰者模式,对输入流进行包装。比如说BufferedInputStream,BufferedOutputStream,DataInputStream,DataOutputStream都是过滤流。
  4. 转换流。

废话不多说,看代码:
使用字节流读取文件内容:

 public void test1(){ File file = new File("F:\\hello.txt"); FileInputStream fis = null; try { //创建一个文件输入流 fis = new FileInputStream(file); //创建一个字节数组用来存储读取的信息 byte[] buf = new byte[1024]; //len表示读取的长度 int len = 0; //只要len大于-1说明读取到元素,可对元素直接进行操作 while((len=fis.read(buf))>-1){ //通过控制台输出程序,需要指明输出的长度 System.out.write(buf,0,len); } } catch (IOException e) { e.printStackTrace(); }finally{ try { if (fis!=null) { //操作完成之后关闭流 fis.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

如何通过操作字节流来实现简单的文件拷贝呢?使用未经包装的输入输出流来拷贝文件,看代码:

 public void test2(){ long startTime = new Date().getTime(); File file = new File("F:\\mysql-installer-community-5.6.22.0.msi"); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(file); fos = new FileOutputStream("F:\\1.msi"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ fos.write(buf, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(fis!=null) fis.close(); } catch (IOException e) { e.printStackTrace(); } try { if(fos!=null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } long endTime = new Date().getTime(); //查看效率 System.out.println((endTime-startTime)/1000); }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

最后的输出结果为2,也就是说拷贝一个接近300M的文件需要两秒钟。

再看看经过BufferedInputStream和BufferedOutputStream包装后的相同文件的拷贝,代码如下:

 public void test3(){ long startTime = new Date().getTime(); File file = new File("F:\\mysql-installer-community-5.6.22.0.msi"); FileInputStream fis = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { fis = new FileInputStream(file); //将fis包装起来 bis = new BufferedInputStream(fis); //将输出流包装 bos = new BufferedOutputStream(new FileOutputStream("F:\\2.msi")); byte[] buf = new byte[1024]; int len = 0; while((len=bis.read(buf))!=-1){ bos.write(buf, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ //关闭流之后会自动flush try { if(bis!=null) bis.close(); } catch (IOException e) { e.printStackTrace(); } try { if(bos!=null) bos.close(); } catch (IOException e) { e.printStackTrace(); } } long endTime = new Date().getTime(); System.out.println((endTime-startTime)/1000); }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

这里的输出为0,也就是说相同的文件拷贝,包装后的流效率会大大提高,原先需要两秒才能完成的拷贝,现在1秒都不到。

再看DataInputStream和DataOutputStream,这两个依然是将InputStream流包装,包装完成之后可以用它写基本类型数据以及字符型数据。

 public void test4(){ FileOutputStream fos = null; DataOutputStream dos = null; DataInputStream dis = null; try { fos = new FileOutputStream("F:\\2.txt"); dos = new DataOutputStream(fos); /** * 每写一个Int类型数据,相当于写入四个字节数据,占四个字节,long是八个字节 * 依次类推 */ dos.writeInt(1111); dos.writeInt(2222); dos.writeInt(3333); dis = new DataInputStream(new FileInputStream("F:\\2.txt")); /** * 每执行一次readInt(),相当于读取四个字节数据,读取其他数据依次类推 */ System.out.println(dis.readInt()); System.out.println(dis.readInt()); System.out.println(dis.readInt()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(dos!=null) dos.close(); } catch (IOException e) { e.printStackTrace(); } try { if(dis!=null) dis.close(); } catch (IOException e) { e.printStackTrace(); } } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

再看看包装后的字符流输入与输出:

 public void test5(){ BufferedReader br = null; PrintWriter out = null; try { br = new BufferedReader(new FileReader("F:\\hello.txt")); out = new PrintWriter(new BufferedWriter(new FileWriter("F:\\11.txt"))); String str = null; while((str=br.readLine())!= null){ System.out.println(str); out.println(str); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(br!=null) br.close(); } catch (IOException e) { e.printStackTrace(); } if(out!=null) out.close(); } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

字节流和字符流之间的转换,可以使用
字符流 =InputStreamReader(字节流)

把从控制台输入的文本内容转存到文本当中:

 public void test6() { BufferedReader br = null; PrintWriter out = null; try { br = new BufferedReader(new InputStreamReader(System.in)); out = new PrintWriter(new BufferedWriter(new FileWriter( "F:\\222.txt"))); String str = null; while ((str = br.readLine()) != null) { if (str.trim().equals("exit")) { break; } System.out.println(str); out.println(str); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) br.close(); } catch (IOException e) { e.printStackTrace(); } if (out != null) out.close(); } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

把一个对象写入到文件中:

 public void writeObject(){ User user = new User("zhangsan","123"); user.setMoney(200); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream("F:\\object.dat")); oos.writeObject(user); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(oos!=null) oos.close(); } catch (IOException e) { e.printStackTrace(); } } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

User.java

import java.io.Serializable;

public class User implements Serializable{ private String username; private String password; //添加了transient属性的字段不会被存储 private transient int money; public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public User() { } public User(String username, String password) { this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

从文件中读取一个对象:

 public void readObject(){ ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream("F:\\object.dat")); User u = (User) ois.readObject(); System.out.println(u.getUsername()+","+u.getPassword()+","+u.getMoney()); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出结果是:
这里写图片描述

由于给money字段添加了transient属性,所以money字段并不会被存储,当然也就读取不到。如果在User.java中删除transient,那么输出结果就是:

这里写图片描述

这个时候money就可被顺利的读取出来。

文章来源: wangsong.blog.csdn.net,作者:_江南一点雨,版权归原作者所有,如需转载,请联系作者。

原文链接:wangsong.blog.csdn.net/article/details/45200689

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。