java基础(IO流)

本文详细介绍了Java中的IO流,包括流的概念、分类和结构。流是数据传输的抽象,分为输入流和输出流,以及字节流和字符流。字节流作为基础,包括InputStream和OutputStream,提供了读写字节的方法。通过实例展示了如何使用字节流从控制台读取和输出数据。理解这些基础知识对于Java开发者至关重要。
摘要由CSDN通过智能技术生成

1.流的概念

在计算机中,流是个抽象的概念,是对输入输出设备的抽象。在Java程序中,对于数据的输入/输 出操作,都是以"流"的方式进行

数据以二进制的形式在程序与设备之间流动传输,就像水在管道里流动一样,所以就把这种数据传输的 方式称之为输入流、输出流。这里描述的设备,可以是文件、网络、内存等

流具有方向性,可以分为输入和输出。
以java程序本身作为参照点,如果数据是从程序“流向”文件,那么这个流就是输出流,如果数据是从文 件“流向”程序,那么这个流就是输入流。例如:
在这里插入图片描述

2. 流的分类

java中的IO流可以根据很多不同的角度进行划分,常见的是以数据的流向和数据的类型来划分

根据数据的流向分为:输入流和输出流
输入流 :把数据从其他设备上读取到程序中的流 输出流 :把数据从程序中写出到其他设备上的流
输出流 :把数据从程序中写出到其他设备上的流

根据数据的类型分为:字节流和字符流
字节流 :以字节为单位(byte),读写数据的流
字符流 :以字符为单位(char),读写数据的流

在这里插入图片描述

字节输入流,在程序中,以字节的方式,将设备(文件、内存、网络等)中的数据读进来
字节输出流,在程序中,以字节的方式,将数据写入到设备(文件、内存、网络等)中
字符输入流,在程序中,以字符的方式,将设备(文件、内存、网络等)中的数据读进来
字符输出流,在程序中,以字符的方式,将数据写入到设备(文件、内存、网络等)中

注意,字节指的是byte,字符指的的是char

3 .流的结构

在Java中,和IO流相关的类,主要是在 java.io 包下的定义的

InputStream ,代表字节输入流类型
OutputStream ,代表字节输出流类型
Reader ,代表字符输入流类型
Writer ,代表字符输出流类型
java中常用的流及其关系结构,如下:
在这里插入图片描述
注意,一般情况下,一个流,会具备起码的三个特点:
是输入还是输出
是字节还是字符
流的目的地

其中,流的目的地指定是: 如果是输入流,就表示这个流从什么地方读数据,如果是输出流,就表示这 个流把数据写到什么地方!

例如, InputStream ,是所有字节输入流的抽象父类型。
那么它的子类型一定是以 字节 的方式,从某个地方把数据 读 取到程序中,只是不同的子类型,它们 的 目的地 不一样,并且一般可以通过子类型的名字看出它的的目的地是哪里,例如:
ByteArrayInputStream ,它是以字节的形式,去读取某个地方的数据,通过名字可以看出,它 的目的地是字节数组中,也就是以字节的形式从byte数组中读取数据
FileInputStream ,它是以字节的形式,去读取某个地方的数据,通过名字可以看出,它的目的

4.字节流

4.1 概述

计算机中,存储一切数据(文本、图片、视频等),都是以二进制的形式进行的,终都是一个一个的字 节,所以使用流,进行传输数据的时候,也是一个一个的字节进行的。
java.io.InputStream 是所有字节输入流的抽象父类型
在这里插入图片描述
InputStream 中核心的三个read方法

//每次读一个字节,返回值是本次读取的字节值
 public abstract int read() throws IOException;
//每次读多个字节,并存放到指定的字节数组中,返回值是本次一共读取了多个字节(字节数)
 public int read(byte b[]) throws IOException {    
 return read(b, 0, b.length); 
 }
//每次读多个字节,并存放到指定的字节数组中,返回值是本次一共读取了多个字节(字节数) //同时可以指定从数组的什么位置开始存放,以及在数组中多存放多个字节 public int read(byte b[], int off, int len) throws IOException {
    if (b == null) {
            throw new NullPointerException();
                } else if (off < 0 || len < 0 || len > b.length - off) {        
                throw new IndexOutOfBoundsException();
                    } else if (len == 0) { 
                           return 0;    
                           }
    int c = read();    
    if (c == -1) { 
           return -1;
               }   
                b[off] = (byte)c;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
注意, InputStream 中的 skip 方法,可以让我们先跳过指定的字节数,再开始读数据
 
java.io.OutputStream 是所有字节输出流的抽象父类型:
 
OutputStream 中核心的三个write方法:
    int i = 1;   
     try {
             for (; i < len ; i++) 
               c = read(); 
               if (c == -1) {
               break;
                           }
             b[off + i] = (byte)c;
             } 
                } catch (IOException ee) { 
                   }    
                   return i;
                    }

java.io.OutputStream 是所有字节输出流的抽象父类型:
在这里插入图片描述
OutputStream 中核心的三个write方法:

//写出去一个字节值 
public abstract void write(int b) throws IOException;
//把一个自己数组中的值全部写出去 
public void write(byte b[]) throws IOException {
    write(b, 0, b.length); 
    }
//写出字节数组,指定开始位置,以及写出的字节数量 
public void write(byte b[], int off, int len) throws IOException {    if (b == null) {        
throw new NullPointerException();    
} else if ((off < 0) || (off > b.length) || (len < 0) ||               ((off + len) > b.length) || ((off + len) < 0)) { 
       throw new IndexOutOfBoundsException();
          } else if (len == 0) { 
                 return;    
                 }    
                 for (int i = 0 ; i < len ; i++) {
                         write(b[off + i]);   
                          } 
                          }

一般情况,使用字节流来操作数据的时候,往往是使用一对,一个字节输入流,负责读取数据, 一个字节输出流,负责将数据写出去,而这些流都将是 InputStream 和 ==OutputStream ==的子类 型
在代码中,使用流操作数据的的基本步骤是:

  1. 声明流
  2. 创建流
  3. 使用流
  4. 关闭流

注意,基本所有流的使用,都是这个套路

4.2 控制台

使用字节流,从控制台读取数据,以及向控制台中写数据。

//The "standard" input stream. 
public final static InputStream in = null;
//The "standard" output stream. 
public final static PrintStream out = null;

PrintStream 是 == OutputStream== 的子类型

public class Test {
    public static void main(String[] args) {
        //1.声明流       
         InputStream in = null;      
           OutputStream out = null;
        //2.创建流,这里使用System中已经创建好的流对象
                in = System.in;       
                 out = System.out;
        //3.使用流
                int data = -1;
                        try { 
                        data = in.read();
                        out.write(data);
                       out.flush();
                       //刷新缓冲区,强制所有数据写出去
                               } catch (IOException e) { 
                               e.printStackTrace();
                                    }finally {
                                     //4.关闭流
                                     if(in!=null) {
                                     try {
                                     in.close();
                                     } catch (IOException e) {
                                     e.printStackTrace();
                                     }
                                     }
            if(out!=null) {
             try { out.close();
              } catch (IOException e) { 
              e.printStackTrace();
               }      
            
             }
        }
    }
}
             



这里是一次读取用一个字节,然后把字节值输出,也可以一次读取多个字节,然后将本次读取到 的都输出

注意,这个子类中重写的read方法,会让线程阻塞,等待用户在控制台中的输入,用户输入并按 下回车,程序中的read方法就从阻塞状态恢复过来,从而读取到用户输入的内容

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值