【Java SE基础 六】Java的IO流实现(上)

简介: 【Java SE基础 六】Java的IO流实现(上)

今天来继续总结一下文件io流,这块儿内容是研一的时候学的,大概时间是2016年1月13日到2016年1月14日学的,现在有些忘记,还好之前的笔记还在,重新梳理一下吧。希望能快速上手。此部分内容,重新整理于2021年1月23日。

IO的意思就是输入输出嘛,主要包括内存,文件等地的输入输出。Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。

  • 一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据

Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中,Java的io包的整体结构如下:

IO流分类

从不同的维度出发,IO流有很多种分类方式,接下来分别介绍:

  1. 依据功能不同,可以划分为节点流/处理流 , 节点流:直接从特定数据源(文件,内存)读写数据;处理流:套在其它已存在流之上的,为程序提供更强大的读写功能
  2. 依据数据单位,可以划分为字节流/字符流 , 字节流:按照8位二进制读;字符流:按照2个8位二进制读,是2个字节
  3. 依据IO流的方向,可以划分为输入流/输出流 ,对此的理解应该站在程序(控制台)的角度上,从文件到程序叫做输入流,从程序到文件叫输出流,读(输入)是读到为程序分配的内存空间中去啦,写(输出)是写到指定的文件中去了。

接下来我们按照这几种符合维度分别讨论下这几种IO流

字节流

字节流分为字节输入流和字节输出流,以及带有buffer缓冲处理的流。

文件字节输入流

文件字节输入流,其类为:FileInputStream ,使用示例如下:

public static void main(String[] args) {
    int b = 0;
    FileInputStream in = null;  //输入字节流
    try {
      in = new FileInputStream("g:\\TML\\TML.txt"); //创建一个管道,新建一个输入流(对接到指定文件)          
    } catch (FileNotFoundException e) {
      System.out.println("找不到指定文件");
      System.exit(-1);
    }
    try { 
      long num=0;
      while((b=in.read())!=-1){  //表示文件还没有读到结尾,读到结尾返回-1   
           //强制转化成字符读取出来,如果不加强转,输出的是一系列对应每个字节的ASCII码数字                    
        System.out.println((char) b);              
        num++;
      }
      in.close(); //一定要记住,读完要关闭读
      System.out.println("共读取了"+num+"个字节");
    } catch (IOException e) {
      System.out.println("文件读取错误");
      System.exit(-1);
    }
  }  //打印出来全是???,因为是一个字节一个字节往出读的,

运行结果,中文汉字发生乱码,因为字节是一个一个读出来的,即使转字符打印,单字节也是半个字符。

A DSFDFDF   DFDF  DFDFDFA 中 国

文件输出字节流

文件字节输入流,其类为:FileOutputStream ,使用示例如下:

public static void main(String[] args) {
    int b = 0;
    FileOutputStream out = null;
    FileInputStream in = null;
    try {
      in = new FileInputStream("g:\\TML\\TML.txt"); // 从文件里读数据
      out = new FileOutputStream("g:\\TML\\ZYJ.txt"); // 往文件里写数据
      int num = 0;
      while ((b = in.read()) != -1) {
        out.write(b);  //写到指定文件中去
        num++;
      }
      in.close();
      out.close();
      System.out.println("共复制了" + num + "个字节");
    } catch (FileNotFoundException e) {
      System.out.println("找不到指定文件");
      System.exit(-1);
    } catch (IOException e) {
      System.out.println("文件复制错误");
      System.exit(-1);
    }
    System.out.println("复制成功");
  }

操作完成后,会产生一个文件内容和复制来源一模一样的文件。

字节缓冲处理流

缓冲输入字节流,其类为:BufferedInputStream ,使用示例如下:

public static void main(String[] args) {
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    int c = 0;
    try {
      fis = new FileInputStream("g:\\TML\\TML.txt");
      bis = new BufferedInputStream(fis);   //把字节流包装到buffer缓冲读入,减少对硬盘的损伤。
      System.out.println((char)fis.read());    //读取第一个字符
      System.out.println((char)bis.read());     //读取第二个字符
      bis.mark(10);  //要求在10个字符之内,这个mark应该保持有效,系统会保证buffer至少可以存储10个字符 
      for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
        System.out.print((char)c + "   ");
      }
      System.out.println();
      bis.reset();                     //回到标记的地方重新读入
      for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
        System.out.print((char)c + "   ");
      }
      bis.close();
    } catch (IOException e) {
      e.printStackTrace();
    }

返回结果如下,可以按行输出:

t
m
l       l   o   v   e       g   u   o   c   
l       l   o   v   e       g   u   o   c

字符流

字符流分为字符输入流和字符输出流,以及带有buffer缓冲处理的流。

文件输入字符流

文件输入字符流,其类为:FileReader ,使用示例如下:

public static void main(String[] args) {
    FileReader fr = null;   //注意,这里是fileReader
    int c = 0;
    try {
      fr = new FileReader("g:\\TML\\TML.txt");      
      while ((c = fr.read()) != -1) {
        System.out.print((char) c); //注意不要换行,打印输出时还是需要char强转,否则读出的是一串数字
      }
      fr.close();
    } catch (FileNotFoundException e) {
      System.out.println("找不到指定文件");
      System.exit(-1);
    } catch (IOException e) {
      System.out.println("文件读取错误");
      System.exit(-1);
    }
  }

此时结果中

A DSFDFDF   DFDF  DFDFDFA 中 国

文件输出字符流

文件输出字符流,其类为:FileWriter ,使用示例如下:

public static void main(String[] args) {
    FileWriter fw = null;
    int c = 0;
    try {
      fw = new FileWriter("g:\\TML\\MHW.txt");
      for (c = 0; c < 200; c++) {
        fw.write("支持茂神的点赞" + c+"   ");
        //只有字符流才能输出字符串,字节流只能输出字符
      }
      fw.close();                        //切记,写完一定要关了,不关资源不释放,无法写入
    } catch (IOException e) {
      System.out.println("文件读取错误");
      System.exit(-1);
    }
    System.out.println("写入成功");
  }

此时会按照字符的模式写入这些内容。

相关文章
|
1天前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
13 1
|
1天前
|
存储 缓存 Java
Java基础17-读懂Java IO流和常见面试题(二)
Java基础17-读懂Java IO流和常见面试题(二)
15 0
|
1天前
|
存储 Java Unix
Java基础17-读懂Java IO流和常见面试题(一)
Java基础16-读懂Java IO流和常见面试题(一)
15 0
|
6天前
|
存储 算法 NoSQL
JAVA—IO流知识点总结
JAVA—IO流知识点总结
|
9天前
|
Java 应用服务中间件
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
|
10天前
|
Java
io读两个文件,生成list 排重后写本地文件(Java)
io读两个文件,生成list 排重后写本地文件(Java)
|
10天前
|
Java Windows
文件操作和IO(2):Java中操作文件
文件操作和IO(2):Java中操作文件
7 0
|
14天前
|
存储 Java API
Java语言IO(输入/输出)编程技术深度解析
Java语言IO(输入/输出)编程技术深度解析
248 1
|
1天前
|
Java API
详细探究Java多线程的线程状态变化
Java多线程的线程状态主要有六种:新建(NEW)、可运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)和终止(TERMINATED)。线程创建后处于NEW状态,调用start()后进入RUNNABLE状态,表示准备好运行。当线程获得CPU资源,开始执行run()方法时,它处于运行状态。线程可以因等待锁或调用sleep()等方法进入BLOCKED或等待状态。线程完成任务或发生异常后,会进入TERMINATED状态。
|
1天前
|
存储 安全 Java
Java多线程中线程安全问题
Java多线程中的线程安全问题主要涉及多线程环境下对共享资源的访问可能导致的数据损坏或不一致。线程安全的核心在于确保在多线程调度顺序不确定的情况下,代码的执行结果始终正确。常见原因包括线程调度随机性、共享数据修改以及原子性问题。解决线程安全问题通常需要采用同步机制,如使用synchronized关键字或Lock接口,以确保同一时间只有一个线程能够访问特定资源,从而保持数据的一致性和正确性。