Java 常见的 IO流
Posted 杨 戬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 常见的 IO流相关的知识,希望对你有一定的参考价值。
文章目录
IO流
IO 流的概念
流是Java对不同输入源输出源的抽象,代表了从起源到接收的有序数据,有了它程序就可以采用统一的方式来访问不同的输入源和输出源了。
从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出
IO 流的分类
按照数据的流向,可以将流分为输入流和输出流。其中,输入流只能读取数据、不能写入数据,而输出流只能写入数据、不能读取数据。
按照数据的类型,可以将流分为字节流和字符流。其中,字节流操作的数据单元是byte(字节),而字符流操作的数据单元是char(16位的字符)。
按照使用的场景,可以将流分为节点流和处理流。其中,节点流可以直接从/向一个特定的IO设备读/写数据,也称为低级流。而处理流则是对节点流的连接或封装,用于简化数据读/写功能或提高效率,也成为高级流。
Java IO流
流实现类
Java中的IO流主要有4个基类:InputStream、OutputStream、Reader、Writer。
- InputStream代表字节输入流
- OutputStream代表字节输出流
- Reader代表字符输入流
- Writer代表字符输出流
其他的IO流都是从这4个基类派生而来的,并且子类的名字往往以基类的名字结尾,所以通过类名我们很容易识别某个流的作用。
Java为我们提供了大量的IO流实现,我们没办法逐个介绍,下面举一些较为常用的例子:
- 用于访问文件的FileInputStream、FileOutputStream、FileReader、FileWriter。
- 带有缓冲功能的BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。
- 具有转换功能的InputStreamReader、OutputStreamWriter。
- 支持打印功能的PrintStream、PrintWriter。
功能说明
文件专属(字节字符流,需要定义数组存储读取/写,read/write 方法)
java.io.FileInputStream(字节输入流,需要byte数组存储,可以读取任何文件)
java.io.FileOutputStream(字节输出流,需要byte数组存储)
java.io.FileReader(文件字符输入流,读取普通文本,需要char数组存储)
java.io.FileWriter(文件字符输出流。只能输出普通文本,需要char数组存储)
缓冲流
java.io.BufferedReader(带有缓冲区的字符输入流,不需要定义数组,有特殊的readLine方法,可以一行一行读)
java.io.BufferedWriter(带有缓冲区的字符输出流,不需要定义数组)
java.io.BufferedInputStream(字节缓冲输入流,效率高,需要定义数组)
java.io.BufferedOutputStream(字节缓冲输出流,效率高,需要定义数组)
转换流(将字节流转换为字符流)
java.io.InputStreamReader (字符字节输入流,将字节输入流转换为字符输入流)
java.io.OutputStreamWriter (字符字节输出流,将字节输出流转换为字符输出流)
打印流
java.io.PrintStream
java.io.PrintWriter
IO流代码应用
FileInputStream
package com.interview.module.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest
public static void main(String[] args) throws FileNotFoundException
//FileInputStream Stream都是字节流 FileInputStream是可以读取任何文件的
FileInputStream fis = null;
try
fis = new FileInputStream("StreamFile/test.txt");
// 开始读,采用byte数组,一次读取多个字节。最多读取“数组.length”个字节。
byte[] bytes=new byte[1024];// 准备一个1024个长度的byte数组,一次最多读取1024个字节。
int readCount = 0;
// 这个方法的返回值是:读取到的字节数量。(不是字节本身);1个字节都没有读取到返回-1(文件读到末尾)
while((readCount = fis.read(bytes)) != -1)
// 不应该全部都转换,应该是读取了多少个字节,转换多少个。
System.out.print(new String(bytes, 0, readCount));
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
finally
// 在finally语句块当中确保流一定关闭。
if (fis != null) // 避免空指针异常!
// 关闭流的前提是:流不是空。流是null的时候没必要关闭。
try
fis.close();
catch (IOException e)
e.printStackTrace();
文件中:
控制台:
FileOutputStream
package com.interview.module.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest
public static void main(String[] args)
FileOutputStream fos = null;
try
// myfile文件不存在的时候会自动新建!
// 这种方式谨慎使用,这种方式会先将原文件清空,然后重新写入。
//fos = new FileOutputStream("myfile");
// 以追加的方式在文件末尾写入。不会清空原文件内容。
fos = new FileOutputStream("StreamFile/test.txt",true);
// 开始写。
byte[] bytes = 97, 98, 99, 100;
// 将byte数组全部写出!
fos.write(bytes); // abcd
// 将byte数组的一部分写出!
fos.write(bytes, 0, 2); // 再写出ab
// 字符串
String s = "我是中国人。";
// 将字符串转换成byte数组。
byte[] bs = s.getBytes();
// 写
fos.write(bs);
// 写完之后,最后一定要刷新
fos.flush();
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
finally
if (fos != null)
try
fos.close();
catch (IOException e)
e.printStackTrace();
文件中:
FileReader
package com.interview.module.io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest
public static void main(String[] args) throws FileNotFoundException
//FileReader 文件字符输入流,只能读取普通文本。读取文本内容时,比较方便,快捷
FileReader reader = null;
try
// 创建文件字符输入流
reader = new FileReader("StreamFile/test.txt");
// 开始读
char[] chars = new char[4]; // 一次读取4个字符
int readCount = 0;
while((readCount = reader.read(chars)) != -1)
System.out.print(new String(chars,0,readCount));
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
finally
if (reader != null)
try
reader.close();
catch (IOException e)
e.printStackTrace();
FileWriter
package com.interview.module.io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterTest
public static void main(String[] args)
//FileWriter文件字符输出流。写。只能输出普通文本。
FileWriter out = null;
try
// 创建文件字符输出流对象
//out = new FileWriter("file");
out = new FileWriter("StreamFile/test.txt", true);
// 开始写。
char[] chars = '你','是','程','序','媛','吗';
out.write(chars);
out.write(chars, 2, 3); // 中国人
out.write("我是一名java程序媛!");
// 写出一个换行符。
out.write("\\n");
out.write("hello girl!");
// 刷新
out.flush();
catch (Exception e)
e.printStackTrace();
finally
if (out != null)
try
out.close();
catch (IOException e)
e.printStackTrace();
文件中:
BufferedReader&InputStreamReader
package com.interview.module.io;
import java.io.*;
public class BufferReaderTest
public static void main(String[] args) throws IOException
FileReader reader = new FileReader("StreamFile/test.txt");
// 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
// 外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
// 像当前这个程序来说:FileReader就是一个节点流。BufferedReader就是包装流/处理流。
BufferedReader br = new BufferedReader(reader);
//BufferedReader br = new BufferedReader( new FileReader("StreamFile/test.txt") );
// br.readLine()方法读取一个文本行,但不带换行符。
String s = null;
while ((s = br.readLine()) != null)
System.out.println(s);
// 关闭流
// 对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭。(可以看源代码。)
br.close();
/*
// 字节流
FileInputStream in = new FileInputStream("StreamFile/test.txt");
// 通过转换流转换(InputStreamReader将字节流转换成字符流。)
// in是节点流。reader01是包装流。
InputStreamReader reader01 = new InputStreamReader(in);
// 这个构造方法只能传一个字符流。不能传字节流。
// reader是节点流。br是包装流。
BufferedReader br01 = new BufferedReader(reader01);
*/
// 合并
// BufferedReader br01 = new BufferedReader(new InputStreamReader(new FileInputStream("StreamFile/test.txt")));
//
// String line = null;
// while ((line = br.readLine()) != null)
// System.out.println(line);
//
//
// // 关闭最外层
// br.close();
BufferedWriter&OutputStreamWriter
package com.interview.module.io;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
public class BufferWriterTest
public static void main(String[] args) throws Exception
//BufferedWriter
BufferedWriter bw=new BufferedWriter( new FileWriter("StreamFile/test.txt"));
bw.write("111");
bw.write("\\n");
bw.write("00000000");
bw.flush();
bw.close();
//OutputStreamWriter 字节流转换成字符流
// 带有缓冲区的字符输出流
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("src/test01.txt", true)));
// 开始写。
out.write("hello world!");
out.write("\\n");
out.write("hello girl!");
// 刷新
out.flush();
// 关闭最外层
out.close();
文件中:
BufferedInputStream&BufferedOutputStream
package com.interview.module.io;
import java.io.*;
public class BufferedInOutputStreamTest
public static void main(String[] args)
String srcFilePath = "C:\\\\Users\\\\Yang\\\\Desktop\\\\test1.jpg";
String destFilePath = "C:\\\\Users\\\\Yang\\\\Desktop\\\\imagestest\\\\test1.jpg";
//创建BufferedInputStream和BufferedOutputStream对象
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
//循环的读取文件,并写入到
byte[] buff = new byte[1024];
int readLen = 0;
//当返回 -1时,就表示文件读取完毕
while((readLen = bis.read(buff)) != -1)
bos.write(buff,0,readLen);
System.out.println("文件拷贝完成~~~");
catch (Exception e)
e.printStackTrace();
finally
//关闭外层的处理流即可,底层去关闭节点流
try
if (bis != null)
bis.close();
if(bos != null)
bos.close();
catch (IOException e)
e.printStackTrace();
文件拷贝成功
以上是关于Java 常见的 IO流的主要内容,如果未能解决你的问题,请参考以下文章