IO流的分类
I/O
是
input/output
的缩写,
I/O
技术是非常实用的技术,用于处理设备之间的数据传输。如:读写文件、网络通信等。在
Java
程序中,对于数据的输入/输出操作以:流(
stream
)的方式进行。
流的分类
-
按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
-
按数据流的流向不同分为:输入流,输出流
-
按流的角色的不同分为:节点流,处理流
(抽象基类) 字节流 字符流 输入流 inputStream Reader 输出流 OutputStream Writer
IO流体系结构
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
FilterInputStream | FilterOutputStream | |||
打印流 | PrintStream | printWiter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
流的使用
对于处理文本文件(
.txt,.java,.c,.cpp
),使用字符流处理。
对于非文本文件(
.jpg,.mp3,.mp4,.avi,.doc,.ppt,....
),使用字节流处理
字符输入流
read()
: 返回读入的一个字符。如果达到文件末尾,返回-1。
异常处理:为了保证流资源一旦执行后,能够执行关闭操作,需要使用
try-catch-findlly
处理。
读入的文件一定要存在,否则就会报
FileNotfoundException
。
public void testFileReader() {FileReader fr = null;try {// 1.实例化File类的对象,指明要操作的文件File file = new File(\"hello.txt\");// 相较于当前Module// 2.提供具体的流fr = new FileReader(file);// 3.数据的读入过程int data = fr.read();while(data != -1) {System.out.print((char)data);data = fr.read();}} catch (IOException e) {e.printStackTrace();} finally {// 4.流的关闭操作try {if(fr != null) fr.close();} catch (IOException e) {e.printStackTrace();}}}
字符输出流
输出操作,对应的File可以不存在的。
File
对应的硬盘中的文件不存在,则在输出的过程中自动创建文件。
File
对应的硬盘中的文件存在:
- 流使用的构造器是
FileWriter(file,false)
或
FileWriter(file)
:对源文件做覆盖。
- 流使用的构造器是
FileWriter(file,true)
:对源文件内做追加。
public void testFileWriter() {FileWriter fileWriter = null;try {// 1.提供File类的对象,指明写出到的文件File file = new File(\"hello1.txt\");// 2.提供FileWriter的对象,用于数据的写出// FileWriter fileWriter = new FileWriter(file);// FileWriter fileWriter = new FileWriter(file,true);FileWriter fileWriter = new FileWriter(file,false);// 3.写出的操作fileWriter.write(\"I have a dream!\\n\");fileWriter.write(\"you need to have a dream!\\n\");} catch (IOException e) {e.printStackTrace();} finally {// 4.流资源的关闭操作if (fileWriter != null) {try {fileWriter.close();} catch (IOException e) {e.printStackTrace();}}}}
字符输入流与字符输出流案例
public void testFileReaderFileWriter() {FileReader fileReader = null;FileWriter fileWriter = null;try {// 1.创建File类对象,指明读入和写出的文件File srcFile1 = new File(\"hello.txt\");File srcFile2 = new File(\"hello2.txt\");// 2.创建输入流与输出流对象fileReader = new FileReader(srcFile1);fileWriter = new FileWriter(srcFile2);// 3.数据的读入与写出操作char[] cbuf = new char[5];int len;// 记录每次读入到数组中字符的个数while((len = fileReader.read(cbuf)) != -1) {// 从0开始,每次写出len个字符fileWriter.write(cbuf,0,len);}} catch (IOException e) {e.printStackTrace();} finally {// 4.关闭流资源103ctry {if (fileWriter != null) fileWriter.close();} catch (IOException e) {e.printStackTrace();}try {if (fileReader != null) fileReader.close();} catch (IOException e) {e.printStackTrace();}}}
字节输入流与字符输出流
FileInputStream
与
FileOutputStream
:使用方法与字符流一致,在处理文本文件是有可能出现乱码。
- 创建File类对象,指明读入和写出的文件。
- 创建输入流与输出流对象。
- 数据的读入与写出操作。
- 关闭流资源。
public void testFileInputOutputStream() {FileInputStream inputStream = null;FileOutputStream outputStream = null;try {File srcFile = new File(\"image.png\");File destFile = new File(\"image2.png\");inputStream = new FileInputStream(srcFile);outputStream = new FileOutputStream(destFile);// 复制的过程byte[] buffer = new byte[5];int len;while((len = inputStream.read(buffer)) != -1) {// 从0开始,每次写出len个字符outputStream.write(buffer,0,len);}} catch (IOException e) {e.printStackTrace();} finally {try {if (outputStream != null) outputStream.close();} catch (IOException e) {e.printStackTrace();}try {if (inputStream != null) inputStream.close();} catch (IOException e) {e.printStackTrace();}}}
处理流:缓冲流
作用:提供流的读取、写入的速度。
缓冲流资源关闭:先关闭外层流(缓冲流),在关闭内层的流(节点流)。
在关闭外层流(缓冲流)的同时,内层流(节点流)也会自动的进行关闭。所有内层的关闭流可以省略。
// 非文本文件的复制public void BufferedStreamTest() {BufferedInputStream bufferedInputStream = null;BufferedOutputStream bufferedOutputStream = null;try {// 1.造文件File srcFile = new File(\"image.png\");File destFile = new File(\"image3.png\");// 2.造流// 2.1 造节点流FileInputStream fileInputStream = new FileInputStream(srcFile);FileOutputStream fileOutputStream = new FileOutputStream(destFile);// 2.2 造缓冲流bufferedInputStream = new BufferedInputStream(fileInputStream);bufferedOutputStream = new BufferedOutputStream(fileOutputStream);// 3.复制的细节:读取、写入byte[] bytes = new byte[10];int len;while ((len = bufferedInputStream.read(bytes)) != -1) {bufferedOutputStream.write(bytes,0,len);}} catch (IOException e) {e.printStackTrace();} finally {// 4.资源关闭// 要求:先关闭外层流,在关闭内层的流try {if (bufferedOutputStream != null) bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}try {if (bufferedInputStream != null) bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}// 在关闭外层流的同时,内层流也会自动的进行关闭。所有内层的关闭流可以省略// fileOutputStream.close();// fileInputStream.close();}}
flush()
:只要是缓冲输出流都会有
flush()
刷新操作。
// 实现文件复制的方法public void copyFileWithBuffered(String srcPath,String destPath) {BufferedInputStream bufferedInputStream = null;15b0BufferedOutputStream bufferedOutputStream = null;try {// 1.造文件File srcFile = new File(srcPath);File destFile = new File(destPath);// 2.造流// 2.1 造节点流FileInputStream fileInputStream = new FileInputStream(srcFile);FileOutputStream fileOutputStream = new FileOutputStream(destFile);// 2.2 造缓冲流bufferedInputStream = new BufferedInputStream(fileInputStream);bufferedOutputStream = new BufferedOutputStream(fileOutputStream);// 3.复制的细节:读取、写入byte[] bytes = new byte[1024];int len;while ((len = bufferedInputStream.read(bytes)) != -1) {bufferedOutputStream.write(bytes,0,len);// bufferedOutputStream.flush();// 刷新缓冲区}} catch (IOException e) {e.printStackTrace();} finally {// 4.资源关闭// 要求:先关闭外层流,在关闭内层的流try {if (bufferedOutputStream != null) bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}try {if (bufferedInputStream != null) bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}}public void testCopyFile() {long start = System.currentTimeMillis();String srcPath = \"F:\\\\视频.avi\";String destPath = \"F:\\\\视频2.avi\";copyFileWithBuffered(srcPath,destPath);long end = System.currentTimeMillis();System.out.println( \"复制文件消耗时间:\" + (end - start));}
readLine()
:一次输出一行,不报行换行符。
newLine()
:提供换行操作。
public void testBufferedReaderBufferedWriter() {BufferedReader bufferedReader = null;BufferedWriter bufferedWriter = null;try {bufferedReader = new BufferedReader(new FileReader(new File(\"hello.txt\")));bufferedWriter = new BufferedWriter(new FileWriter(new File(\"hello3.txt\")));String data;while((data = bufferedReader.readLine()) != null) {bufferedWriter.write(data);// data中不包含换行符bufferedWriter.newLine();// 提供换行操作}} catch (IOException e) {e.printStackTrace();} finally {// 关闭资源try {if (bufferedWriter != null) bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}try {if (bufferedReader != null) bufferedReader.close();} catch (IOException e) {e.printStackTrace();}}}
处理流:转换流
转换流提供了在字节流和字符流之间的转换:
InputStreamReader
(属于字符流):将一个字节的输入流,转换为字符的输入流。
OutputStreamWriter
(属于字符流):将一个字符的输出流,转换为字节的输出流。
public void test2() {InputStreamReader inputStreamReader = null;OutputStreamWriter outputStreamWriter = null;try {File file1 = new File(\"dbcp.txt\");File file2 = new File(\"dbcp_gbk.txt\");FileInputStream fileInputStream = new FileInputStream(file1);FileOutputStream fileOutputStream = new FileOutputStream(file2);inputStreamReader = new InputStreamReader(fileInputStream,\"UTF-8\");outputStreamWriter = new OutputStreamWriter(fileOutputStream,\"GBK\");char[] cbuf = new char[1024];int len;while((len = inputStreamReader.read(cbuf)) != -1) {outputStreamWriter.write(cbuf,0,len);}} catch (IOException e) {e.printStackTrace();} finally {try {if (outputStreamWriter != null) outputStreamWriter.close();} catch (IOException e) {e.printStackTrace();}try {if (inputStreamReader != null) inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}}}