使用io流后要手动关闭吗(IO低级流)

在java中,将不同的输入输出源通过流的形式进行相关操作(输入,输出),流是一种抽象描述,在程序中表示数据的一种转移方式。将IO比喻为"流",即:stream. 就像生活中的"电流","水流"一样,它是以同一个方向顺序移动的过程.只不过这里流动的是字节(2进制数据).所以在IO中有输入流和输出流之分,我们理解他们是连接程序与另一端的"管道",用于获取或发送数据到另一端

使用io流后要手动关闭吗(IO低级流)(1)

理解:流(stream)

  • 按流向分站在程序角度考虑
    1. 输入流(input)
    2. 输出流(output)
  • 按类型分:
  1. 字节流(InputStream/OutputStream) 任何文件都可以通过字节流进行传输。【最基本的字节输入/输出流,抽象类,定义了读取/写入原始字节的所有基本方法】
  2. 字符流(Reader/Writer) 非纯文本文件,不能用字符流,会导致文件格式破坏,不能正常执行。
  3. 节点流(低级流:直接跟输入输出源对接) FileInputStream/FileOutputStream/FileReader/FileWriter/PrintStream/PrintWriter.【节点流的另一端是明确的,是实际读写数据的流,读写一定是建立在节点流的基础上进行的】
  4. 处理流(高级流:建立在低级流的基础上)

转换流:InputStreamReader、OutputStreamWriter,字节流转字符流/字符流转字节流

缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedReader可对节点流经行包装,使读写更快

【注】实际应用中,我们可以通过串联一组高级流到某个低级流上以流水线式的加工处理对某设备的数据进行读写,这个过程也成为流的连接,这也是IO的精髓所在.

使用io流后要手动关闭吗(IO低级流)(2)

理解 低级流和高级流关系

常用IO流继承关系图

InputStream:字节输入抽象类(做各个字节输入类的祖先基类)

使用io流后要手动关闭吗(IO低级流)(3)

InputStream

OutputStream:字节输出抽象类(做各个字节输出类的祖先基类)

使用io流后要手动关闭吗(IO低级流)(4)

OutputStream

Reader:字符输入抽象类(做各个字符输入类的祖先基类)

使用io流后要手动关闭吗(IO低级流)(5)

Reader

Writer:字符输出抽象类(做各个字符输出类的最终基类)

使用io流后要手动关闭吗(IO低级流)(6)

Writer

小Demo案例:

  • 写入数据到文件中(FileOutputStream-低级流)

//向当前目录下的demo.dat文件中写入数据 /* FileOutputStream提供的常用构造器 FileOutputStream(String path) FileOutputStream(File file) */ //文件流创建时,如果该文件不存在会自动将其创建(前提是该文件所在目录必须存在!) FileOutputStream fos = new FileOutputStream("./fos.dat"); /* void write(int d) 向文件中写入1个字节,写入的内容是给定的int值对应的2进制的"低八位" int值 1: vvvvvvvv 二进制:00000000 00000000 00000000 00000001 demo.dat文件内容: 00000000 */ fos.write(1); /* vvvvvvvv 00000000 00000000 00000000 00000010 demo.dat文件内容 00000001 00000010 */ fos.write(2); fos.close();

  • 读取文件数据(FileInputStream-低级流)

/* int read() 读取一个字节,并一int型返回。返回的整数中读取的字节部分在该整数2进制的最后8位上 如果返回值为整数-1,则表示流读取到了末尾。对于读取文件而言就是EOF(end of file文件末尾) 调用read(): int d = fis.read(); fos.dat文件内容 00000001 00000011 ^^^^^^^ 读取该字节 返回int值时,2进制样子: 00000000 00000000 00000000 00000001 ^^^^^^^ |-----补充24个0(3字节)-----| 读取的字节 返回的int值d就是上述内容 */ FileInputStream fis = new FileInputStream("fos.dat"); int d = fis.read(); //返回值为整数-1,则表示流读取到了末尾 System.out.println(d); fis.close();

  • 文件复制(低级流实现)

//创建文件输入流读取原文件 FileInputStream fis = new FileInputStream("image.jpg"); //创建文件输出流写入复制文件 FileOutputStream fos = new FileOutputStream("image_cp.jpg"); int d;//保存每次读取到的字节 /* 原文件数据: 11000011 10101010 00001111 11001100 00110011 ... ^^^^^^^ d = fis.read(); d:00000000 00000000 00000000 10101010 fos.write(d); 复制文件的数据: 11000011 10101010 */ long start = System.currentTimeMillis();//获取当前系统时间的毫秒值(UTC时间) while((d = fis.read()) != -1) { fos.write(d); } long end = System.currentTimeMillis();//获取当前系统时间的毫秒值(UTC时间) System.out.println("复制完毕!耗时:" (end-start) "ms"); fis.close(); fos.close();

  • 块读写的文件复制操作(byte[] 低级流)

int read(byte[] data); // 一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。 返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。 //块写操作 void write(byte[] data); 一次性将给定的字节数组所有字节写入到文件中 void write(byte[] data,int offset,int len); 一次性将给定的字节数组从下标offset处开始的连续len个字节写入文件 //通过提高每次读写的数据量,减少实际读写的次数,可以提高读写效率。 //单字节读写是一种随机读写形式。而一组一组字节的读写是块读写形式。 //创建文件输入流读取原文件 FileInputStream fis = new FileInputStream("wnwb.exe"); //创建文件输出流写复制文件 FileOutputStream fos = new FileOutputStream("wnwb_cp.exe"); /* 流提供了块读写的方法 int read(byte[] data) 一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。 返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。 */ int len;//记录每次实际读取的字节量 byte[] data = new byte[1024*10]; //10kb long start = System.currentTimeMillis(); //获取utc标准时间的毫秒值 while((len = fis.read(data))!=-1){ fos.write(data,0,len);//读取多少就写多少 } long end = System.currentTimeMillis(); System.out.println("复制完毕!耗时:" (end-start) "ms"); fis.close(); fos.close(); //流使用完毕后 须关闭

  • 写入文本数据(getBytes() 低级流)

//String提供方法: byte[] getBytes(String charsetName); 将当前字符串转换为一组字节 参数为字符集的名字,常用的是UTF-8。 其中中文字3字节表示1个,英文1字节表示1个。 //UTF-8: char是2字节,3z字节表示,就是拆开以 1110xxxx 10xxxx 10xxxx 把2字节分开写入x位置. //当第二个参数传入true时,文件流为追加模式,即:指定的文件若存在, // 则原有数据保留,新写入的数据会被顺序的追加到文件中 FileOutputStream fos = new FileOutputStream("demo.txt",true); String str = "企业订单发布会,全球贸易交流"; byte[] data = str.getBytes("UTF-8"); //把字符转成字节 fos.write(data); //传入上面定义的字符串 fos.write("八月正午的阳光,都没你耀眼。".getBytes("UTF-8")); System.out.println("写出完毕!"); fos.close(); //写完要关闭流

  • 读取文本数据(低级流)

FileInputStream fis = new FileInputStream("fos.txt"); byte[] data = new byte[1024]; int len = fis.read(data);//块读操作 System.out.println("实际读取到了" len "个字节"); /* String提供了将字节数组转换为字符串的构造方法: String(byte[]data,String charsetName) 将给定的字节数组中所有字节按照指定的字符集转换为字符串 String(byte[]data,int offset,int len,String charsetName) 将给定的字节数组从下标offset处开始的连续len个字节按照指定的字符集转换为字符串 */ String line = new String(data,0,len,"UTF-8"); //String 提供的方法 System.out.println(line); System.out.println(line.length()); fis.close();

学习记录,如有侵权请联系删除。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页