理解IO流笔记(自用)

理解IO流

标准输入输出数据流:java.lang.System:

java.lang.System;
public final class System extends Object{
    static PrintStream err;//标准错误流(输出)
    static InputStream in;//标准输入流(键盘输入流)
    static PrintStream out;//标准输出流(显示器输出流)
}

System类不能创建对象,只能直接使用它的三个静态成员

main方法被执行时就会自动生成上面的三个对象

一、标准输出流(System.out)

System.out向标准输出设备输出数据,数据类型为PrintStream

​ void print(参数);

​ void println(参数);

print(Object)和println(Object)方法在运行时会自动调用参数Object和toString方法。

二、标准输入流(System.in)

System.in从标准输入设备上获取输入,数据类型是InputStream

int read();//返回ASCII码,若返回-1表示没有读取到任何字符表示没有读取到任何字节

int read(byte[] b);//读入多个字符节到缓冲区b中,返回读取字节

三、标准错误流(System.err)

System.err输出标准错误,数据类型为PrintStream

四、java.IO层次体系结构

五个类:File、OutputStream、InputStream、Writer、Reader

一个接口:Serializable

  1. 流式部分——IO的主体部分

  2. 非流式部分——辅助流式工作的类。如:File类、RandomAccessFile类和FileDescriptor等类;

  3. 其他类——与文件读取安全相关的类,如:SerializablePermission类;以及与本地操作系统相关的文件系统的类。如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

    主要的类如下:

  4. File(文件特征与管理):用于文件或者目录的描述信息

  5. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类,定义了所有输入流的共同特征。

  6. OutputStream(二进制格式操作):抽象类,基于字节的输出操作,是所有输出流的父类,定义了所有输出流的共同特征。

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示

  7. Reader(文件格式操作):抽象类,基于字符的输入操作

  8. Writer(文件格式操作):抽象类,基于字符的输出操作

  9. RandomAccessFile(随机文件操作):从文件的任意位置进行存取操作

    存取:输入输出操作

在这里插入图片描述

1、非流式文件类——File类

在java.io包中,File类提供了描述文件和目录的操作与管理办法,专门用来管理文件和目录,不提供输入输出。不是InputStream、OutputStream、Writer、Reader的子类

作用:主要用于命名文件,查询文件属性和处理文件目录

public class File extends Object implements Serializable,Comarable{}

构造函数

File(String pathname)
	File f1 = new File("test1.txt");//f1在当前目录下被创建

File(String parent , String child)
	File f2 = new File("D:\\dir1","test2.txt");
    //d:\\dir1存在的情况下,在dir1下创建一个test.2txt

File(File parent , String child)
    File f3 = new File("\\dir2");
    File f4 = new(f4,"test3.txt");//在dir2下创建一个test3.txt文件

mkdir()创建文件对象指定的目录(单层目录)
createNewFile()创建文件对象指定的文件
list()返回目录中所有文件名字符串

2、Java.IO流类库

2.1 IO流的四个基本类

java.io包中包含了流式I/O所需要的所有类。

基本数据流

输入/输出字节流字符流
输出流InputStreamReader
输入流OutputStreamWriter

JDK1.4版本开始引入了新I/O类库,位于java.nio包中,新I/O类库利用通道和缓冲区来提高I/O操作的效率。

2.2 IO流的具体分类

一、按I/O类型来总体分类:

  1. Memory
    1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
    2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream

  2. Pipe管道

    ​ 实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream

  3. File 文件流

    ​ 对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream

  4. ObjectSerialization

    ​ 对象输入、输出 :ObjectInputStream、ObjectOutputStream

  5. DataConversion数据流

    ​ 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream

  6. Printing

    ​ 包含方便的打印方法 :PrintWriter、PrintStream

  7. Buffering缓冲

    ​ 在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream

  8. Filtering 滤流

    ​ 在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过

  9. Concatenation合并输入

    ​ 把多个输入流连接成一个输入流 :SequenceInputStream

  10. Counting计数

    ​ 在读入数据时对行记数 :LineNumberReader、LineNumberInputStream

  11. Peeking Ahead

    ​ 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream

  12. Converting between Bytes and Characters

    ​ 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

二、按数据来源(去向)分类

  1. File(文件): FileInputStream、FileOutputStream、FileReader、FileWriter
  2. byte[]:ByteArrayInputStream、ByteArrayOutputStream
  3. Char[]:CharArrayReader,CharArrayWriter
  4. String:StringBufferInputStream、StringBufferOutputStream,StringReader,StringWriter
  5. 网络数据流:InputStream、OutputStream、Reader、Writer

五、字节流InputStream和OutputStream

1、InputStream抽象类

InputStream类提供了3种重载的read方法

  1. public abstract int read();读取一个字节的数据,返回值类型为int,若返回-1则表示没有读取到任何 字节

  2. public int read(byte b[]);读取b.length个字节的数据放在b数组中,返回值是读取的字节数

  3. public int read(byte b[],int off,int len);从输入流中最多读取len个字节的数据,放在偏移量为off的数组b中

  4. public int available();返回输入流中可以读取的字节数,这个方法必须由继承InputStream类的子类调用才有用

  5. public long skip(long n);跳过输入流中的几个字节,返回值是忽略的字节数

  6. public int close();关闭已打开的流

  7. 主要子类:

在这里插入图片描述

​ 1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作
   2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
   3) StringBufferInputStream:把一个String对象作为InputStream
   4) PipedInputStream:实现了pipe的概念,主要在线程中使用
   5) SequenceInputStream:把多个InputStream合并为一个InputStream

2、OutputStream抽象类

OutputStream提供了3个write方法

  1. public abstract void write(int b);先将int转化为byte类型,把低字节写入到输出流中。

  2. public void write(byte b[]);将数组b中的字节写到输出流

  3. public void write(byte b[],int off,int len);将数组b中从偏移量off开始的额len个字节写入到输出流中

  4. public void flush();将数据缓冲区中的数据全部输出,并清空缓冲区

  5. public void close();关闭已打开的流

  6. 主要子类:
    在这里插入图片描述

​ 1)ByteArrayOutputStream:把信息存入内存中的一个缓冲区中

​ 2)FileOutputStream:把信息存入文件中

​ 3)PipedOutputStream:实现了pipe的概念,主要在线程中使用

​ 4)SequenceOutputStream:把多个OutputStream合并为一个OutputStream
流程结束的判断:方法read()的返回值为-1时,readLine()的返回值为null时。

3、文件输入输出流FileInputStream/FileOutputStream

3.1 文件输入流FileInputStream类

FileInputStream使用read()方法一次读一个字节返回值类型为int;使用read()方法读入一个byte数组,byte数组通常扮演承接数据的中间角色。

作用:打开文件,把文件中数据读到内存中

//使用方法一
File fi = new File("d:/abc.txt");
FileInputStream in = new FileInputStream(fi);

//使用方法2
FileInputStream in = new FileInputStream("d:/abc.txt");

将InputFromFile.java的程序的内容显示在显示器上

import java.io.IOException;
import java.io.FileInputStream;

public class TestFile{
    public static void main(String[] args) throws IOException{
        try{
            FileInputStream rf = new FileInputStream("InputFromFile.java");
            int n = 512;
            byte[] buffer= new byte[n];
            while((rf.read(buffer,0,n)!=-1)&&n>0){
                System.out.println(new String(buffer));
            }
            System.out.println();
            rf.close();
        }catch(IOException IOe){
            System.out.println(IOe.toString());
        }
    }
}
3.2文件输出流FileOutputStream类

作用:将数据从内存区读入文件

一个表示文件名的字符串也可以是File或FileDescriptor对象

//创建的第一种方法
File fi = new File("d:/abc.txt");
FileOutputStream out = new FileOutputStream(fi);

//创建的第二种方法
FileOutputStream out = new FileOutputStream("d:/abc.txt");

//方式3:构造函数将FileDescriptor()对象作为参数
FileDescriptor fd = new FileDescriptor();
FileOutputStream out = new FileOutputStream(fd);

//方式4:构造函数将文件名作为第一参数,将布尔值作为第二参数
FileOutputStream out = new FileOutoutStream("d:/abc.txt",true);

注:文件中写数据时,若文件已存在,覆盖存在的文件

使用键盘输入一段文章,将文章保存在 文件write.txt中

import java.io.IOException;
import java.io.FileOutputStream;

public class TestFile{
    public static void main (String[] args) throws IOException{
        try{
            System.out.println("please Input from Keyboard");
            int count = 0;
            int n = 512;
            byte[] buffer = new byte[n];
            count = System.in.read(buffer);
            FileOutputStream out = new FileOutStream("d:/myjava/write.txt");
            out.write(buffer,0,count);
            out.close();
            System.out.println("Save to the.write.txt");
        }catch(IOException IOe){
            System.out.println("File Write Error!");
        }
    }
}
3.3 FileInputStream流和FileOutputStream的应用

将file1.txt复制到file2.txt中

import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FileInputStream;

public class TestFile{
    public static void main(String[] args)throws IOException{
        try{
            int count;
            File in = new File("file1.txt");
            File out = new File("file2.txt");
            FileInputStream infile = new FileInputStream(in);
            FileOutputStream outfile = new FileOutputStream(out);
            //判断如果输入流不为空进行循环内操作
            while((count = infile.read()) != -1){
                //写入file2.txt文件中
                outfile.write(count);
            }
            //关闭输入流
            infile.close();
            //关闭输出流
            outfile.close();
        }catch(IOException IOe){
            System.out.println(IOe);
        }
    }
}

4、缓冲输入输出流 BufferedInputStream/BufferedOutputStream

BufferedInputStream

​ 计算机访问外存的频率越高,造成CPU闲置的概率就越大,为了减少对外存的访问次数,我们应该一次读写尽量多的数据。因此增加了缓冲机制,缓冲流就是每一个数据流分配一个缓冲区,这样可以提高传输效率。

​ BufferedInputStream比FileInputStream多了一个缓冲区,它提供了一个缓冲数组,调用read()方法首先从缓冲数组中读取数据,如果缓冲数组中没有数据,则选择从物理数据源中读取数据放入缓冲区中。BuffferedInputStream默认缓冲大小是8192字节。每次读取的数据量很小时FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。BufferedInputStream效率高。当BUFFER_SIZE>8192时缓冲池输入流和文件输入流效率没有明显的差别。

BufferedOutputStream

​ 执行write时先写入缓冲区,待缓冲区写满后再写入输出设备

将文件读入内存:

FileInputStream in = new FileInputStream(file);
BufferedInputStream bin = new BufferedInputStream(in);
bin.read();
bin.close();

将内存写入文件:

String fileB = "/User/zhangyingying/b.txt";
FileOutputStream out = new FileOutputStream(fileB);
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] buffer = {0x1,0x2,0x3};
bout.write(buffer);
bout.flush();
bout.close();

键盘输入流到读到内存

import java.io.*;

public class Testfile{
    public static void main(String[] args){
        //字符流
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        FileWriter out = new FileWriter("myfile.txt");
        BuferedOutputStream bout = new BufferedWriter(out);
        String s;
        While((s = dr.readLine()).length() > 0){
            bout.write(s,0,length());
        }
    }
}

String readLine():读取一行字符串,以回车符结束

bout.write(String s ,offset ,len)从缓冲区将字符串s从offset开始,len长度的字符串写到某处。

六、字符流Reader和Writer

​ java中字符采用unicode编码,一个字符是16位,一个字符由两个字节组成。

1、Reader抽象类

用于读取字符流的抽象类。子类必须实现read(char[],int,int)和close(),多数子类会重写定义的一些方法

在这里插入图片描述

FileReader:用于 读取字符文件中的数据,使用缺省的字符编码

​ 构造函数

  1. FileReader fr = new FileReader(“test.txt”);——文件名做字符串

  2. File对象做字符串

    File file =new File(“test.txt”);

    FileReader fileReader = new FileReader(file);

  3. FileDescriptor对象作为参数

    FileDescriptor() fd = new FileDescriptor();

    FileReader fileReader = new FileReader(fd);

CharArrayReader

  1. 用字符数组作为参数:CharArrayReader(char[]);
  2. 将字符数组作为输入流:CharArrayReader(char[],int,int);

StringReader

  1. 读取字符串,构造函数如下:public StringReader(String s);

InputStreamReader

​ 输入流读取字节将字节流转换为字符流

​ public InputStreamReader(InputStream is);

FilterReader:允许过滤字符流

​ protected filterReader(Reader r)

BufferReader:接受Reader对象作为参数,并对其添加字符缓冲器

​ 可以使用readLine()方法读取一行

​ public BufferReader(Reader r);

  1. public int read();读取一个字符,返回值为读取的字符;
  2. public int read(char cbuf[],int off, int len);读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量子类必须实现

2、Writer抽象类

子类必须实现write(char[],int,int)、flush()、close()方法

其子类:

在这里插入图片描述

FileWriter

​ 将字符类型写入文件

​ public FileWriter(file f);

CharArrayWriter

​ 将字符缓冲器用作输出

​ public CharArrayWriter();

PrintWriter:生成格式化输出

​ public PrintWriter(outputstream os);

FilterWriter:用于写入过滤字符流

​ protected FilterWriter(Writer w);

PipedWriter:与PipedOutputStream对应

**StringWriter:无与之对应的以字节为导向的stream **

主要方法

(1) public void write(int c); //将整型值c的低16位写入输出流
  (2) public void write(char cbuf[]); //将字符数组cbuf[]写入输出流
  (3) public abstract void write(char cbuf[],int off,int len); //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
  (4) public void write(String str); //将字符串str中的字符写入输出流
  (5) public void write(String str,int off,int len); //将字符串str 中从索引off开始处的len个字符写入输出流
  (6) flush( ) //刷空输出流,并输出所有被缓存的字节。
  (7) close( ) //关闭流 public abstract void close() throws IOException

七、InputStream和Reader的区别

  1. InputStream输入流为字节流,最小单位是字节;Reader输入流为字符流,在处理字符流时涉及了字符编码转换问题。
  2. Reader能将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存

八、OutputStream和Writer的区别

  1. OutputStream输出流为字节流最小单位是字节,Writer输出流为字符流,在处理字符流时涉及了字符编码转换问题
  2. Writer能将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

在这里插入图片描述

九、BufferedInputStream和BufferedReader的区别

BufferedInputStream实现的时候在自身的read()方法中提供缓存,是一次取1024或更多字节然后再读,最后一个个的返回。没有实现读一行的方法

BufferReader可以通过readLine()方法实现读一行(回车为结束符),可以使用数组或StringBuilder存储一行数据,并一次性返回。

十、FileWriter(字符输出流类)

构造方法

//创建字符输出流类对象和文件相关联,如果文件不在的话创建一个文件。

FileWriter file = new FileWriter(String FileName);

//创建一个字符输出流类对象和文件关联,并且设定是否续写,false为不续写(原来文件内容会被覆盖掉),true为续写。

FileWriter file = new FileWriter(Srting FileName, boolean append);

主要方法

//写入字符串,此时的字符串还没有到达被写入文件中,暂存在缓冲区中,写入之后使用flush()方法刷新,数据才会被存储到目的文件中。

void write(String str);

//刷新对应的输出流,将缓冲区中的数据保存到对应文件中去

void flush();

//关闭输出流,在关闭之后再写入或刷新会抛出异常

void close();

十一、FileReader(字符输入流)

构造方法

//第一种构造方法,创建输入流对象与文件相关联

FileReader fileReader = new FileReader(“test.txt”);

//第二种构造方法,创建文件对象,创建输入流对象,通过文件对象与相对应文件相关联。

File file = new File(“test.txt”);

FileReader fileReader = new FileReader(file);

主要方法

int read();

int read(char[] c);

int read(char[] c,off,len);

int read(CharBuffer target);

void close();

十二、如何选择IO流

1、确定是数据源还是数据目的

  • 源:输入流 InpurtStream/Reader
  • 目的:输出流 OutputStream/Writer

2、操作对象是否纯文本

  • 是:Reader、Writer
  • 否:InputStream、OutputStream

3、具体设备

  • 硬盘文件:File+

    • 读取:FileInputStream、FileReader
    • 写入:FileOutputStream、FileWrite
  • 内存:数组

    • byte[]:ByteArrayInputStream、ByteArrayOutputStream

    • char[]:CharArrayReader、CharArrayWriter

    • String:StringBufferInputStream(过时,只能用于String的每个字符都是8位的字符串),StringReader,StringWriter

    • 网络(Socket流):输出socket.getOutputStream();输出socket.getInputStream()

    • 键盘:输入System.in()读取;输出System.out()打印;

      Scanner scan = new Scanner(System.in);

4、是否需要转换流

​ 是:InputStreamReader/OutputStreamWriter

5、是否需要缓冲提高效率

​ 是:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

6、是否需要格式化输出

​ 将一个文件中数据存储到另一个文件中。JAVA的文件读取主要有字节流读取和字符流读取两种方式,字节流可以既可以操作文本文件,也可以操作非文本文件,如一些二进制数据(图片,视频,对象),而字符流只能操作文本。

十三、IOException异常类的子类

  1. public class EOFException:非法到达文件尾或输入流尾的时候,抛出这种异常;
  2. public class FileNotFoundException:当文件找不到时,抛出异常;
  3. public class InterruptedIOExcception:I/O操作被中断时,抛出这种异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值