学习笔记:Java_I/O(part_two)
来源:互联网 发布:电动车用骑行导航软件 编辑:程序博客网 时间:2024/06/16 19:11
I/O流
(概述、文件字节流、文件字符流、转换流、缓冲流)
IO流这部分,算上学习File文件类的时间,总共花了三天时间学习,知识庞杂,种类繁多。但是说到底,各种各样的IO流,核心的方法无外乎构造()、read()、write()三种,根据文件类型的不同,选取不同的IO流。
东西太多,一次整理不完,因此分成几篇文章来整理,这里是IO概述、文件字节流、文件字符流、转换流四部分
I/O流概述
输入输出的概念
- 输入输出指的是系统内存与外部设备,网络等进行交互的过程。
|
I/O概念
流是一个抽象的概念。当Java程序需要从数据源读取数据时,会开启一个到数据源的流,这个流就是输出流,数据源可以是文件,内存或者网络等。同样,当程序需要输出数据到目的地时也一样会开启一个流,这个流就是输入流,数据目的地也可以是文件、内存或者网络等。流的创建是为了更方便地处理数据的输入输出。
流对象的操作依赖于操作系统,流通道本身并没有作用。
流分类
- 四大父类(抽象基类)
* 根据是否具有额外功能:
OutputStreamWriter 输入转换流
输出转换流 字节和字符 转换字节到字符 缓冲流 BufferedXXX XXX的功能 XXX的操作对象 可以通过缓冲原理实现加速并且实现一些新功能
流对象操作步骤
- 创建流子类对象,绑定数据目的(数据源和目标文件)
- 调用流方法进行读写操作
- .close();释放流对象(Java在程序结束时会自动关闭所有打开的流,但即便如此,显式的关闭任何打开的流仍是一个良好的习惯)。
I/O流注意事项
- I/O流只能对整个文件进行操作,对文件中个别数据进行操作只能用数据库才能实现。
- 流对象进行操作的时候经常会抛出IOException异常,所以需要用try{}catch{}语句来写。
文件字节流和文件字符流
主要区别
- 文件字节流可以读写任意文件(不包括文件夹),每次只操作文件中的一个字节。利用字节流创建的新文件可以保证不出错。
- 文件字符流只能读写文本文件(用.txt格式打开之后能读懂的文件就是文本文件),用字符流创建除文本文件以外任意文件都会造成文件损坏。
- 字节流不能直接操纵unicode字符,这时字符流的必要性就体现出来,因为一次操纵一个字符(即两个字节),这样就避免了数据传输中,汉字出现乱码等问题。
文件字节流
文件字节输入流
构造器
- 作用是绑定输入数据源
文件字节输入流有两种构造方法:
——————————
|FileInputStream(String filePath);|
|FileInputStream(File file); |
——————————示例代码
/** 这里是在方法内对异常进行处理的完整步骤,比较麻烦,不如throws之后在外边处理好用* 这里只举例输入流的例子,输出流大同小异,定义时候的区别在其他代码里体现。*/import java.io.File;import java.io.FileInputStream;import java.io.IOException;public class MyInputStream { public static void main(String[] args) { File file = new File("d:\\java\\全职高手.txt"); FileInputStream in = null;//try外定义方便显式关闭输入流; try { in = new FileInputStream(file); } catch (IOException ea) { ea.getMessage();//打印错误信息; throw new RuntimeException("\n运行发生错误,请尝试重新运行:");//关闭程序; } finally { try { if (in != null)//判断输入流是否存在且创建成功; in.close(); } catch (IOException eb) { eb.getMessage(); throw new RuntimeException("\n输入流关闭失败,请尝试重新运行程序"); } } }}
常用方法
b的大小太大会浪费空间,太小又影响速度,所以一般定义大小为1024 read(byte b[], int off, int len) int(实际读取的字节个数) off指定数据存放在数组中的位置,len指定方法读取的最大字节数 close(); void 显式关闭输入流
文件字节输出流
构造器
- 作用是绑定输出的输出目的
文件字节输出流有四种构造方法:
———————————————-
|FileOutputStream(String filePath); |
|FileOutputStream(File file); |
|FileOutputStream(String filePath, boolean append); |
|FileOutputStream(File file, boolean append); |
———————————————-输出流对象的构造方法可以创建对象,但是如果源文件存在,默认会覆盖原来的文件。
所有在构造方法的参数后边常常可以添加另外一个参数boolean append来决定如果文件存在是否覆盖,当apped**值为true**时,输出流会创建新文件覆盖目标文件,否则不覆盖,在目标文件中进行续写。
常用方法
b的大小太大会浪费空间,太小又影响速度,所以一般定义大小为1024 write(byte b[], int off, int len) void off指定数据存放在数组中的位置,即偏移量,len指定方法写入的最大字节数 close(); void 显式关闭输出流
文件字符流
* 转换流失文件字符流的父类,继承关系:
* java.io.FileReader extends java.io.inputStreamReader;
* java.io.inputStreamReader extends java.io.Reader;
* java.io.Reader extends java.lang.Object;
* 文件字符输入流和文件字符输出流都采用系统默认的编码表,中文版Windows系统默认系统编码表为GBK;
文件字符输入流
构造器
- 作用是绑定输入数据源
- 文件字符输入流有两种构造方法:
————————–
|FileReader(String filePath);|
|FileReader(File file); |
————————–
常用方法
b的大小太大会浪费空间,太小又影响速度,所以一般定义大小为1024 read(byte b[], int off, int len) int(实际读取的字符个数) off指定数据存放在数组中的位置,len指定方法读取的最大字节数 close(); void 显式关闭输入流
文件字节输出流
构造器
- 作用是绑定输出的输出目的
- 文件字符输出流有四种构造方法:
—————————————-
|FileWriter(String filePath); |
|FileWriter(File file); |
|FileWriter(String filePath, boolean append); |
|FileWriter(File file, boolean append); |
————————————– - 输出流对象的构造方法可以创建对象,但是如果源文件存在,默认会覆盖原来的文件。
- 所有在构造方法的参数后边常常可以添加另外一个参数boolean append来决定如果文件存在是否覆盖,当apped**值为true**时,输出流会创建新文件覆盖目标文件,否则不覆盖,在目标文件中进行续写。
- 与文件字节输出流不同,文件字符输出流只能创建有效的文本文件。
常用方法
每次写入数据后进行一次冲流是一个好习惯 close(); void 显式关闭输出流,再关闭流的同时进行一次冲流操作
文件字节流复制文件代码举例
import java.io.*;class ClsByte { private String originalpath, finalpath; private long starttime, endtime; public ClsByte(String a, String b) { this.originalpath = a; this.finalpath = b; } public void function() { System.out.println("字节流复制文件,开始执行:"); starttime = System.currentTimeMillis(); File orifile = new File(originalpath); File tarfile = new File(finalpath); FileOutputStream out = null; FileInputStream in = null; byte[] data = new byte[1024]; try { in = new FileInputStream(orifile); out = new FileOutputStream(tarfile, false); int len = 0; while ((len = in.read(data)) != -1) { out.write(data, 0, len); } } catch (IOException e) { e.getStackTrace(); throw new RuntimeException("\n文件传输中发生错误,请重试"); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { throw new RuntimeException("\n输入流关闭失败,请重试"); } try { if (out != null) { out.close(); } } catch (IOException e) { throw new RuntimeException("\n输出流关闭失败,请重试"); } } endtime = System.currentTimeMillis(); System.out.println("文件复制成功\n源文件" + orifile.getAbsolutePath() + "源文件大小" + orifile.getTotalSpace() + "B"); System.out.println("目标文件" + tarfile.getAbsolutePath() + "目标文件大小" + tarfile.getTotalSpace() + "B"); System.out.println("消耗时间" + (endtime - starttime) + "millseconds"); }}
文件字符流复制文件代码举例
import java.io.*;import java.util.*;class ClsChar { private String originalpath, finalpath; private long starttime, endtime; public ClsChar(String a, String b) { this.originalpath = a; this.finalpath = b; } public void function() { System.out.println("\n字符流复制文件,开始执行:"); starttime = System.currentTimeMillis(); File orifile = new File(originalpath); File tarfile = new File(finalpath); FileReader in = null; FileWriter out = null; char [] data = new char [1024]; try { in = new FileReader(orifile); out = new FileWriter(tarfile, false); int len = 0; while ((len = in.read(data)) != -1) { out.write(new String(data, 0, len)); out.flush(); } } catch (IOException e) { e.getStackTrace(); throw new RuntimeException("\n文件传输中发生错误,请重试"); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { throw new RuntimeException("\n输入流关闭失败,请重试"); } try { if (out != null) { out.close(); } } catch (IOException e) { throw new RuntimeException("\n输出流关闭失败,请重试"); } } endtime = System.currentTimeMillis(); System.out.println("文件复制成功\n源文件" + orifile.getAbsolutePath() + "源文件大小" + orifile.getTotalSpace() + "B"); System.out.println("目标文件" + tarfile.getAbsolutePath() + "目标文件大小" + tarfile.getTotalSpace() + "B"); System.out.println("消耗时间" + (endtime - starttime) + "millseconds"); }}
转换流
转换流特性
两种转换流都是字符流,区别在于,Output是由字符转字节,Input是由字节转字符
转换流和文件字符流的区别
- 文件字符流是转换流的子类
- 文件字符流的编码表已指定为系统默认编码表,转换流则可以指定编码表
FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
*
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。FileReader fr = new FileReader("a.txt");
- 这三句代码的功能是一样的,其中第三句最为便捷。
- 注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?
- 条件:
- 操作的是文件。
- 使用默认编码。
- 条件:
构造器
- InputStreamReader(InputStream in)
- 创建的转换流使用默认字符集
- InputStreamReader(InputStream in, Charset cs)
- 创建的转换流使用指定的字符集”cs”
- OutputStreamWriter(OutputStream out)
- 创建的转换流使用默认字符集
- OutputStreamWriter(OutputStream out, Charset cs)
- 创建的转换流使用指定的字符集”cs”
缓冲流
- Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度。缓冲流必须指向一个底层流,底层流负责将数据读入缓冲区,缓冲流再从缓冲区中读取数据。
- 根据流的分类分类字节缓冲流与字符缓冲流。
- 字节缓冲流(BufferedReader/BufferedWriter)的底层流是字节流(InputStream/OutputStream);
- 字符缓冲流(BufferedInputStream/BufferedOutputStrean)的底层流是字符流(Reader/Writer)。
构造器
- 四种缓冲流的构造器各有两种,这里拿字符缓冲输入流举例:
方法
字节缓冲流
BufferedInputStream/BufferedOutputStream的方法基本都继承自InputStream/OutputStream,没有什么自己独特的方法,这里不再赘述
字符缓冲流
同样,这里对于从父类中继承的方法(read(), write(), close(), flush())等都不再赘述,只介绍一些独特的方法。
* 字符缓冲输出流
但其实在Windows系统下,在字符串尾部或头部写入“\r\n”是一样的效果
- 字符缓冲输入流
缓冲字符流复制文件代码举例
import java.io.*;public class ClsBufferedByte { private String originalpath, finalpath; private long starttime, endtime; public ClsBufferedByte(String a, String b) { this.originalpath = a; this.finalpath = b; } public void function() { System.out.println("\n缓冲字节流复制文件,开始执行:"); starttime = System.currentTimeMillis(); File orifile = new File(originalpath); File tarfile = new File(finalpath); BufferedInputStream in = null; BufferedOutputStream out = null; FileInputStream rootin = null; FileOutputStream rootout = null; byte[] data = new byte[1024]; try { rootin = new FileInputStream(orifile); rootout = new FileOutputStream(tarfile); in = new BufferedInputStream(rootin); out = new BufferedOutputStream(rootout); int len = 0; while ((len = in.read(data)) != -1) { out.write(data, 0, len); } } catch (IOException e) { e.getStackTrace(); throw new RuntimeException("\n文件传输中发生错误,请重试"); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { throw new RuntimeException("\n输入流关闭失败,请重试"); } try { if (out != null) { out.close(); } } catch (IOException e) { throw new RuntimeException("\n输出流关闭失败,请重试"); } } endtime = System.currentTimeMillis(); System.out.println("文件复制成功\n源文件" + orifile.getAbsolutePath() + "源文件大小" + orifile.getTotalSpace() + "B"); System.out.println("目标文件" + tarfile.getAbsolutePath() + "目标文件大小" + tarfile.getTotalSpace() + "B"); System.out.println("消耗时间" + (endtime - starttime) + "millseconds"); }}
缓冲字符流复制文件代码举例
import java.io.*;public class ClsBufferedChar { private String originalpath, finalpath; private long starttime, endtime; public ClsBufferedChar(String a, String b) { this.originalpath = a; this.finalpath = b; } public void function() { System.out.println("\n缓冲字符流复制文件(按行读取),开始执行:"); starttime = System.currentTimeMillis(); File orifile = new File(originalpath); File tarfile = new File(finalpath); BufferedReader in = null; BufferedWriter out = null; FileReader rootin = null; FileWriter rootout = null; String data = null; try { rootin = new FileReader(orifile); rootout = new FileWriter(tarfile); in = new BufferedReader(rootin); out = new BufferedWriter(rootout); while ((data = in.readLine()) != null) { out.write(data); out.flush(); } } catch (IOException e) { e.getStackTrace(); throw new RuntimeException("\n文件传输中发生错误,请重试"); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { throw new RuntimeException("\n输入流关闭失败,请重试"); } try { if (out != null) { out.close(); } } catch (IOException e) { throw new RuntimeException("\n输出流关闭失败,请重试"); } } endtime = System.currentTimeMillis(); System.out.println("文件复制成功\n源文件" + orifile.getAbsolutePath() + "源文件大小" + orifile.getTotalSpace() + "B"); System.out.println("目标文件" + tarfile.getAbsolutePath() + "目标文件大小" + tarfile.getTotalSpace() + "B"); System.out.println("消耗时间" + (endtime - starttime) + "millseconds"); }}
- 学习笔记:Java_I/O(part_two)
- 学习笔记:Java_I/O(B)
- 学习笔记:Java_I/O(part_one)
- Java_I/O流
- Winsock I/O 学习笔记
- Java I/O学习笔记
- Java I/O学习笔记
- I/O流学习笔记
- 【Java学习笔记】I/O
- java I/O 学习笔记
- I/O流学习笔记
- Java I/O 学习笔记(7) new I/O
- JAVA I/O系统学习笔记-部分
- 学习笔记I/O篇之一
- 学习笔记I/O篇之二
- 学习笔记I/O篇之三
- 学习笔记I/O篇之四
- 学习笔记I/O篇之五
- 大数据IMF传奇行动绝密课程第115课:超大规模spark性能优化本质思考
- ListView始终显示垂直滚动条设置
- MongoDB学习记录05-原子性操作
- 数组(三)
- 八项提高机器学习模型的准确率的方法
- 学习笔记:Java_I/O(part_two)
- 怎样创建一个HTML文件
- win10+gtx1070+tensorflow+cuda8.0+cudn搭建深度学习环境
- mysql5.7新特性组复制官网简易翻译
- HTML5学习笔记——1
- 方差的含义
- 大一下学期课程设计
- CentOS 6.5下安装Tomcat
- [XSIM 43-3225] Cannot find design unit xil_defaultlib.simple_ram_tb in library work located at xsim.