IO流基本概念 Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输、上传文件和下载文件 ,Java用于操作流的对象都在IO包中。
IO流分为字节流、字符流和其它流,总来说是五类一接口 其他类基本都是他们的延申:类 File、InputStream、OutputStream、Reader、Writer、RandomAccess和接口Serializable,其中InputStream、OutputStream属于字节流,Reader、Writer属于字符流。区分字节流和字符流可以通过这种方式:如果我们能在自己电脑上用笔记本打开一个文件,那么就可以用字符流去处理它,如果不行就用字节流。因为字符流只能处理文本数据 而字节流可以处理任何类型的文件数据。
字节流 1 2 3 4 基类 InputStream |__文件操作流 FilterInputStream |__缓冲流 BufferedInputStream |__对象流 ObjectInputStream
字节流基础类 InputSream:抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
序号
方法名
解释
1
abstract int read()
从输入流中读取数据的下一个字节
2
int read(byte[] b)
从输入流读取一些字节数,并将它们存储到缓冲区 b
3
int read(byte[] b, int off, int len)
从输入流读取最多 len字节的数据到一个字节数组。
4
void close()
关闭此输入流并释放与该流关联的所有系统资源
OutputStream: OutputStream:抽象类,基于字节的输出操作,是所有输出流的父类。定义了所有输出流都具有的共同特征。
序号
方法名
解释
1
void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流
2
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
3
abstract void write(int b)
将指定的字节写入此输出流
4
void close()
关闭此输出流并释放与此流有关的所有系统资源
5
void flush()
刷新此输出流并强制写出所有缓冲的输出字节
FileInputStream:字节文件输入流,从文件系统中的某个文件中获得输入字节,用于读取诸如图像数据之类的原始字节流。
FileOutputStream:字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。
1 2 FileInputStream常用方法:read()、close() FileOutputStream常用方法:write()、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 29 30 31 32 public void fileInputStrameTest () throws IOException { FileInputStream fileInputStream = new FileInputStream("E:\\1.txt" ); int by; while ((by=fileInputStream.read())!=-1 ) { System.out.print((char )by); } fileInputStream.close(); } public void fileOutputStreamTest () throws IOException { FileOutputStream fileOutputStream = new FileOutputStream("E:\\2.txt" ,true ); Scanner scanner = new Scanner(System.in); while (scanner.hasNextInt()){ int a = scanner.nextInt(); fileOutputStream.write(a); } scanner.close(); byte b = 0b1111011 ; fileOutputStream.write(b); fileOutputStream.write('\n' ); byte [] c = "123abc" .getBytes(); System.out.println(c); fileOutputStream.write(c); fileOutputStream.close(); }
BufferedInputStream
和BufferedOutputStream
类就是实现了缓冲功能的输入流/输出流。使用带缓冲的输入输出流,效率更高,速度更快。这两个类分别是FilterInputStream
和FilterOutputStream
的子类,作为装饰器子类,使用它们可以防止 每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
我们有必要知道不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
同时正因为它们实现了缓冲功能,所以要注意在使用BufferedOutputStream
写完数据后,要调用flush()
方法或close()
方法 ,强行将缓冲区中的数据写出。否则可能无法写出数据。与之相似还BufferedReader
和BufferedWriter
两个类。
1 2 3 4 5 构造方法: // 创建一个 BufferedInputStream并保存其参数,即输入流in,以便将来使用。 BufferedInputStream(InputStream in) // 创建具有指定缓冲区大小的 BufferedInputStream并保存其参数,即输入流in以便将来使用 BufferedInputStream(InputStream in, int size)
BufferedOutputStream:字节缓冲输出流,提高了写出效率。
1 2 3 4 5 6 7 8 9 10 11 12 构造方法: // 创建一个新的缓冲输出流,以将数据写入指定的底层输出流 BufferedOutputStream(OutputStream out) // 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流 BufferedOutputStream(OutputStream out, int size) 常用方法: // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流 void write(byte[] b, int off, int len) // 将指定的字节写入此缓冲的输出流 void write(int b) // 刷新此缓冲的输出流 void flush()
示例:
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 public void bufferInputStreamTest () throws IOException { BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:\\1.txt" )); byte [] s1=new byte [1024 ]; int len; while ((len=bufferedInputStream.read(s1))!=-1 ) { System.out.print(new String(s1,0 ,len)); } bufferedInputStream.close(); } public void bufferOutputStreamTest () throws IOException { OutputStream outputStream = new FileOutputStream("E:\\2.txt" ); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); bufferedOutputStream.write("好的我明白" .getBytes()); bufferedOutputStream.flush(); } public void bufferTest () throws IOException { InputStream inputStream = new FileInputStream("E:\\1.txt" ); FileOutputStream fileOutputStream = new FileOutputStream("E:\\2.txt" ); byte [] buffer = new byte [1024 ]; int len; while ((len=inputStream.read(buffer))!=-1 ){ fileOutputStream.write(buffer,0 ,len); } inputStream.close(); fileOutputStream.flush(); }
ObjectInputStream 和 ObjectOutputStream 的作用是对基本数据和对象进行序列化操作支持。 Serialization(序列化)是一种将对象转换为字节流的过程;反序列化deserialization是将字节流转换为对象的过程。 一个对象如果想要进行序列化,那么该对象的类必须实现Serializable接口 。
示例在最后,因为涉及了字符流。
字符流 1 2 3 4 基类 Reader |__字节转字符 转换流 InputStreamReader |__文件操作流 FileReader |__字符缓冲流 BufferReader
字符流基础类-Reader&Writer Reader:抽象类,基于字节的输入操作,是所有输入字符流的父类。
序号
方法
解释
1
int read()
读取单个字符
2
int read(char[] cbuf)
将字符读入数组
3
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分
4
long skip(long n)
跳过字符
5
abstract void close()
关闭该流并释放与之关联的所有资源
Writer:抽象类,基于字节的输出操作,是所有输出字符流的父类。
序号
方法
解释
1
void write(char[] cbuf)
写入字符数组
2
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分
3
void write(int c)
写入单个字符
4
void write(String str)
写入字符串
5
void write(String str, int off, int len)
写入字符串的某一部分
6
abstract void close()
关闭此流,但要先刷新它
7
abstract void flush()
刷新该流的缓冲
InputStreamReader:字节流转字符流,它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
OutputStreamWriter:字节流转字符流。
示例:
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 inputStreamReaderTest () throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\1.txt" )); char [] c = new char [1024 ]; int len; while ((len=inputStreamReader.read(c))!=-1 ){ System.out.println(new String(c,0 ,len)); } inputStreamReader.close(); } public void outputStreamWriterTest () throws IOException { OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\2.txt" ),"GBK" ); String s = "123发士大夫艰苦" ; outputStreamWriter.write(s); outputStreamWriter.flush(); } public void test () throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\1.txt" )); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\2.txt" ),"GBK" ); char [] c = new char [1024 ]; int len; while ((len=inputStreamReader.read(c))!=-1 ){ outputStreamWriter.write(c); } inputStreamReader.close(); outputStreamWriter.flush(); }
字符文件操作流-FileReader&FileWriter FileReader:从InputStreamReader类继承而来。该类按字符读取流中数据。
FileWriter :从 OutputStreamWriter 类继承而来。该类按字符向流中写入数据。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public static void main (String[] args) throws IOException { FileTest fileTest = new FileTest(); fileTest.fileWriterTest(); fileTest.fileReaderTest("E:\\2.txt" ); } public void fileReaderTest (String filename) throws IOException { FileReader fileReader = new FileReader(filename); char [] c = new char [1024 ]; int len; while ((len=fileReader.read(c))!=-1 ){ System.out.println(new String(c,0 ,len)); } fileReader.close(); } public void fileWriterTest () throws IOException { FileWriter fileWriter = new FileWriter("E:\\2.txt" ,true ); String s = "123456哈哈哈" ; fileWriter.write(s); fileWriter.flush(); }
字符缓冲流 字符缓冲流 BufferedReader和BufferedWriter跟字节缓冲流类似,只不过一个是字符一个是字节,BufferedReader和BufferedWriter是Reader和Writer的子类。
示例:
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 public class BufferTest { public static void main (String[] args) throws IOException { BufferTest bufferTest = new BufferTest(); bufferTest.bufferWriterTest(); bufferTest.bufferReaderTest(); } public void bufferReaderTest () throws IOException { BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\2.txt" )); String s; while ((s=bufferedReader.readLine())!=null ) { System.out.println(s); } bufferedReader.close(); } public void bufferWriterTest () throws IOException { BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\2.txt" ,true )); bufferedWriter.newLine(); bufferedWriter.write("123123开发了" ); bufferedWriter.flush(); bufferedWriter.close(); } }
对象流示例 示例:序列化一个对象之后,反序列化这个对象,并执行该对象的方法。另外更详细的说明可以看下之前的笔记Java序列化和反序列化
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 class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { Test test = new Test(); test.objectToStreamTest(); test.streamToObjectTest(); } public void objectToStreamTest() throws IOException { //对象转字节流 FileOutputStream fileOutputStream = new FileOutputStream("E:\\1.txt"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); Person person = new Person(); objectOutputStream.writeObject(person); objectOutputStream.close(); } public void streamToObjectTest() throws IOException, ClassNotFoundException { //字节流转对象 ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\1.txt")); Person person1 = (Person) objectInputStream.readObject(); person1.run(); } } class Person implements Serializable{ public void run() throws IOException { //获取当前程序环境 Runtime runtime = Runtime.getRuntime(); //执行命令 Process process = runtime.exec(new String[]{"ipconfig","/a"}); //用缓冲区读取执行结果 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String s; while ((s=bufferedReader.readLine())!=null){ System.out.println(s); } } }
参考链接:
https://www.kuangstudy.com/bbs/1356043480895451137
https://blog.csdn.net/SUN__CGJ/article/details/109467222
https://www.cnblogs.com/zhaoyanjun/p/6376937.html
https://www.cnblogs.com/yuler/p/11990543.html