JAVA——流(Stream)输入输出流

谁借莪1个温暖的怀抱¢ 2023-02-17 11:26 63阅读 0赞

目录

        • 什么是流?
          • 文件输入/输出流:
          • 字节输入/输出流:
            • 以字节流的形式 读取文件内容/向文件写入内容
            • 字节流读取:
            • 字节流写入:
          • 使用字符流 读取/写入文件:
          • 缓存流:
          • 使用缓存流读取数据:
          • 使用缓存流输出数据到文件:
          • flush:有的时候,需要立即把数据写入到硬盘中,而不是等到缓存满了才写出去。这时候就需要用到flush
          • 对象流:

什么是流?

什么是流(Stream),流就是一系列的数据
流是个抽象的概念,是对输入输出设备的抽象,当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至时候其他的程序
比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流:InputStream
输出流:OutputStream

文件输入/输出流:

建立一个文件输入流,这个流可以用来把数据从硬盘的文件读取到JVM(虚拟机)内
这段代码只是建立一个流,并没有开始读取操作

建立一个文件输出流,这个流可以用来把内存中的数据写入到硬盘的文件中
这段代码只是建立一个流,并没有开始写入操作;

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. public class TestStream {
  6. public static void main(String[] args) throws FileNotFoundException {
  7. // 创建基于文件的输入流
  8. File file = new File("D:\\CloudMusic\\测试小说输入.txt");
  9. // 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中
  10. FileInputStream fileInputStream=new FileInputStream(file);
  11. //创建基于文件的输出流
  12. File file1 = new File("D:\\CloudMusic\\测试小说输出.txt");
  13. //通过这个输出流,就可以将内存中的数据,输出到硬盘的文件中
  14. FileOutputStream fileOutputStream = new FileOutputStream(file1);
  15. }
  16. }
字节输入/输出流:

InputStream字节输入流
OutputStream字节输出流
用于以字节的形式读取和写入数据

以字节流的形式 读取文件内容/向文件写入内容
字节流读取:

InputStream是字节输入流,同时也是抽象类,只提供方法的声明,不提供方法的实现,FileInputStream是InputStream的子类,以FileInputSream为例进行文件读取:

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. public class TestStream {
  5. public static void main(String[] args) throws IOException {
  6. //准备文件 测试.txt 其中的内容为ABCD
  7. File f = new File("D:/CloudMusic/测试.txt");
  8. //创建基于文件的输入流
  9. FileInputStream fis=new FileInputStream(f);
  10. //创建一个字节数组,长度为文件的长度
  11. byte [] all=new byte[(int)f.length()];
  12. //以字节流的形式读取文件的所有内容
  13. fis.read(all);
  14. for (byte b : all) {
  15. System.out.println(b);
  16. }
  17. //使用完流之后应进行关闭
  18. fis.close();
  19. }
  20. }

在这里插入图片描述
打印出来的是65,66,67,68是因为ABCD,对应的ASCII分别是65 66 67 68 ;

字节流写入:

OutoutStream是字节输出流,同时也是抽象类,只提供方法的声明,不提供方法的具体实现
FileOutputStream是OutputStream的子类,以FileOutputStream为例向文件写入数据。
注: 如果文件D:/CloudMusic/测试1.txt的测试1.txt文件不存在,写出操作会自动创建该文件。
但是如果是文件D:/CloudMusic/测试1.txtt,的目录CloudMusic不存在,会抛出异常

  1. import java.io.File;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. public class TestStream {
  5. public static void main(String[] args) throws IOException {
  6. //准备文件 测试1.txt 其中的内容是空的
  7. File f = new File("D:/CloudMusic/测试1.txt");
  8. //创建一个字节数组,长度为文件的长度
  9. byte [] date = {
  10. 88,89};
  11. //创建基于文件的输出流
  12. FileOutputStream fos=new FileOutputStream(f);
  13. //把数据写入到输出流
  14. fos.write(date);
  15. //使用完流之后应进行关闭
  16. fos.close();
  17. }
  18. }

在以字节流向文件中写入数据时,当文件不存在时,会自动创建文件并写入数据,而当目录不存在时,会抛出异常。解决办法是:获取该文件所在的目录(getParentFile();)然后判断是否存在(exists();),不存在则创建目录(mkdirs)使用mkdirs则会创建完整目录。

使用字符流 读取/写入文件:

读取文件信息
FileReader是reader的子类,以FileReader为例进行文件读取

  1. import java.io.File;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. public class TestStream {
  5. public static void main(String[] args) {
  6. File f = new File("D:/CloudMusic/测试.txt");
  7. try {
  8. FileReader fr= new FileReader(f);
  9. char [] date = new char[(int) f.length()];
  10. fr.read(date);
  11. for (char c : date) {
  12. System.out.print(c);
  13. }
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. }
  18. }

以字符的形式将文件中的信息读取出来

将信息写入文件
FileWriter是Writer的子类,以FileWriter为例,把字符串写入到文件

  1. import java.io.File;
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. public class TestStream {
  5. public static void main(String[] args) {
  6. File f = new File("D:/CloudMusic/caca.txt");
  7. try {
  8. FileWriter fw=new FileWriter(f);
  9. String date = "abcdedf1234567890";
  10. fw.write(date);
  11. fw.close();
  12. } catch (IOException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }
缓存流:

当我们在硬盘上进行读写操作时,都会访问硬盘,如果读写的频率较高的时候,就会耗费大量的性能。为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读取较多的数据到缓存中去,以后的每一次读取,都在缓存中访问,知道缓存中的数据读取完毕,再到硬盘中去读取。
这就好比吃饭,不用缓存就是每吃一口饭都到锅里面去铲。而使用缓存就是先把饭盛到碗里去,碗里面的吃完了,再到锅里去铲。
缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区 达到一定量,才把这些数据一起写入到硬盘中去。按照这种操作,就不会像字节流那样,每写一个字节都访问硬盘,从而减少了IO操作。

使用缓存流读取数据:
  1. import java.io.*;
  2. public class TestStream {
  3. public static void main(String[] args) throws IOException {
  4. //随便准备一个有内容的文件
  5. File f = new File("D:/CloudMusic/测试小说.txt");
  6. //创建文件字符流
  7. FileReader fr=new FileReader(f);
  8. //缓存流必须建立在一个已经存在的流 的基础上
  9. BufferedReader br=new BufferedReader(fr);
  10. while(true){
  11. //一次读取一行
  12. String line = br.readLine();
  13. if(null==line){
  14. break;
  15. }
  16. System.out.println(line);
  17. }
  18. }
  19. }
使用缓存流输出数据到文件:
  1. import java.io.*;
  2. public class TestStream {
  3. public static void main(String[] args) throws IOException {
  4. File f = new File("D:/CloudMusic/测试.txt");
  5. // 向文件 测试.txt中写入三行语句
  6. FileWriter fw = new FileWriter(f);
  7. BufferedWriter bw= new BufferedWriter(fw);
  8. bw.write("全球最大的中文搜索引擎");
  9. bw.newLine();//添加一个新的行,相当于换行符
  10. bw.write("致力于让网民更便捷地获取信息,找到所求。");
  11. bw.newLine();
  12. bw.write("百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。");
  13. /*关闭流,如果不关闭的话,会存在缓存中,待虚拟机关闭后
  14. *就会消失(数据不会写入到硬盘中)
  15. */
  16. bw.close();
  17. }
  18. }
flush:有的时候,需要立即把数据写入到硬盘中,而不是等到缓存满了才写出去。这时候就需要用到flush
  1. import java.io.*;
  2. public class TestStream {
  3. public static void main(String[] args) throws IOException {
  4. File f = new File("D:/CloudMusic/测试.txt");
  5. // 向文件 测试.txt中写入三行语句
  6. FileWriter fw = new FileWriter(f);
  7. BufferedWriter bw= new BufferedWriter(fw);
  8. //不添加close关闭流,就没有将信息写入到文件
  9. bw.write("全球最大的中文搜索引擎");
  10. bw.flush();
  11. bw.newLine();//添加一个新的行,相当于换行符
  12. bw.write("致力于让网民更便捷地获取信息,找到所求。");
  13. bw.newLine();
  14. bw.write("百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。");
  15. }
  16. }

在这里插入图片描述
可以看到后面的两条字符串都没有写入到文件中

对象流:

对象流指的是可以直接把一个对象以流的形式传输给其他介质,比如硬盘等
一个对象以流的形式进行传输,叫做序列化。该对象所对应的类,必须实现Serializable接口
注意:一个对象序列化有一个前提:这个对象类,必须实现了Serializable接口
序列化: 是对象转换成一个字节序列的过程,是一个写操作

  1. class.Msg implements Serializable{
  2. }
  3. ObjectOutStream oos = new ObjectOutputStream
  4. //(文件输入流/网络输出流)
  5. oos.writeObject();
  6. oos.flush();
  7. oos.close()

反序列化: 一个字节序列转换成对象的过程 ,是一个读操作

  1. ObjectInputStream ois = new ObjectInputStream
  2. //(文件输入流/网络输入流)
  3. Msg msg = Msgois.readObject();
  4. ois.close()

发表评论

表情:
评论列表 (有 0 条评论,63人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java输入输出

      一、什么是IO   Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流

    相关 JAVA 输入/输出

    JAVA 输入/输出流 本次分3个部分详细解说关于Java.io的使用 1、标准设备输入/输出 a) 标准输入/输出类System. System类提供的静态方法中,分别...