Java-IO流学习总结

来源:互联网 发布:刷天猫搜索流量软件 编辑:程序博客网 时间:2024/05/28 05:18

Java-IO流学习总结

一.理解java中的流是相对于谁而言?

java中的流,可从不同角度进行分类
(1)数据流的方向:输入流,输出流
输出流:其中数据源指的是程序要读写的一个源头,可以是一个文件等

输入流:

(2)处理数据单位:字节流,字符流
字节流:一次操作8位二进制
字符流:一次操作16位二进制
(3)实现功能:节点流,处理流
节点流:直接与数据源相连,读或者写
处理流:配合节点流一起使用,在节点流的基础上封装

二.java中的常用IO流

(1)顶层父类

1.Reader:以字符为单位的输入流的超类,他提供了reader接口来取字符数据
字段:protected Object lock,同步针对此流的操作对象  方法:  public int read(CharBuffer target) throws IOException,将字符读入指定的字符缓冲区  public int read() throws IOException,读取单个字符  public int read(char[] cbuf) throws IOException,读取字符数组bstract public int read(char cbuf[], int off, int len) throws IOException,读取字符数组,从off开始,读取len长度  public long skip(long n) throws IOException,跳过n个字符数    public boolean ready() throws IOException,是否准备读取此流  public boolean markSupported(),是否支持标记,返回false  public void mark(int readAheadLimit) throws IOException,标记流中的当前位置  public void reset() throws IOException,重置流  
2.Writer:以字符为单位的输出流的超类,提供了write()接口写入数据
字段:   private char[] writeBuffer;临时字符数组存储    private final int writeBufferSize = 1024;默认写入字符长度protected Object lock;同步针对此流的操作对象方法:构造函数不做赘述public Writer append(CharSequence csq) throws IOException;追加指定字符序列到输出流  
3.InputStrem:以字节为单位的输入流的超类,提供了read()接口从输入流中读取字节数据
字段:  private static final int MAX_SKIP_BUFFER_SIZE = 2048;最大跳过的字节单位  方法:  public int read(byte b[], int off, int len);将字符读入数组中,起始位置off,长度len  public long skip(long n);跳过n个字节  public synchronized void mark(int readlimit);标记流中的当前位置  public boolean markSupported();是否支持标记,false,不支持  public synchronized void reset() throws IOException,同样不支持重置  
4.OutputSteam:以字节为单位的输出流的超类,提供了write()接口从输出流中读取数据
方法: public void write(byte b[], int off, int len)从指定字节数字中开始位置off,写入len个长度到输出流  

(2)字符输入流:

1.字符数组输入流:CharArrayReader
字段:  protected char buf[];字符缓冲数组  protected int pos;下一个被读取的位置  protected int markedPos = 0;标记位置  protected int count;字符缓冲的长度  方法:  public CharArrayReader(char buf[]) 构造函数, 根据buf创建流对象,设置读取位置为0,长度为buf长度  public CharArrayReader(char buf[], int offset, int length),构造函数,创建流对象,设置读取位置为offset,长度为length,如果长度非法抛出IllegalArgumentException  private void ensureOpen(),判断缓冲流是否有效,字符缓冲为空,无效  public int read() ,读取下一个字符,返回字符缓冲区中下一位置的值  public int read(char b[], int off, int len),读取数据,保存到字符数组b中,从off开始的位置,len读取长度  public long skip(long n) ,跳过n个字符  public boolean ready() ,判断能否读取下一个字符  public boolean markSupported(),是否支持标记,永远返回true  public void mark(int readAheadLimit) ,保存当前位置,mark()必须和reset()配置才会生效  public void reset(),重置下一个读取位置为mark所标记的位置  
2.FileReader:用于读取字符流的类,继承InputStreamReader,这个类不做过多解释
3.PipedReader:通过管道进行线程间的通信,使用管道通信,必须将PipedReader和PipedWriter配合使用
字段: boolean closedByWriter = false;标记管道输出流是否关闭  boolean closedByReader = false;标记管道输入流是否关闭  boolean connected = false;管道输入流和输出流是否连接的标记,它在管道输出流的connect()连接函数中为true  Thread readSide;读取管道数据的线程  Thread writeSide; 向管道写入数据的线程  private static final int DEFAULT_PIPE_SIZE = 1024;管道的默认大小  char buffer[];缓冲区  int in = -1;下一个写入字符的位置,当in==out代表写入数据全部都被读取了  int out = 0;下一个读取字段的位置  函数&方法:  public PipedReader(PipedWriter src):构造函数,指定与PipedWriter关联  private void initPipe(int pipeSize);初始化管道,新建缓冲区大小  public void connect(PipedWriter src);将管道输出流和输入流绑定synchronized void receive(int c);接受int类型的数据  synchronized void receive(char c[], int off, int len),接受字符数组  public synchronized int read(),从管道缓冲区中读取一个字符,并转换为int  public synchronized int read(char cbuf[], int off, int len),从管道缓冲区中读取数据  public synchronized boolean ready(),能否从管道中读取下一个数据  public void close(),关闭管道输入流     
4.InputStreamReader:将字节输入流转换为字符输入流
函数&方法:  public InputStreamReader(InputStream in),根据in创建InputStreamReader,使用默认编码  public InputStreamReader(InputStream in, String charsetName),使用指定编码  public InputStreamReader(InputStream in, CharsetDecoder dec),使用解码器  public int read(),读取并返回一个字符  public int read(char cbuf[], int offset, int length),将InputStreamReader中的数据写入cbuf中,从offset位置写,长度length  public boolean ready(),能否从InputStreamReader中读取数据
5.BufferedReader: 会将Reader中的数据分批读取,每一次取一部分数据到缓冲区中,操作完缓冲区中的数据之后,再从Reader中再读取,因为缓冲区中的数据在内存中,可以使读取数据提高
字段:  private Reader in;  private char cb[];字符缓冲区  private int nChars, nextChar;nChars缓冲区中字符总数,nextChar下一个要读取的字符在缓冲区中的位置  private static final int INVALIDATED = -2;“标记无效”,标记过,但是被标记位置太长,导致无效  private static final int UNMARKED = -1;没用被标记,压根就没标记过  private int markedChar = UNMARKED;标记  private int readAheadLimit = 0; “标记”能标记位置的最大长度  private boolean skipLF = false;是否忽略换行符标记  private static int defaultCharBufferSize = 8192;设置字符缓冲区大小  private static int defaultExpectedLineLength = 80;默认每一行的字符个数  函数&方法:  public BufferedReader(Reader in, int sz),创建Reader对应的BufferedReader,sz是BufferedReader的缓冲区大小  private void ensureOpen() 确保BufferedReader是打开的状态  private void fill(),填充缓冲区,(1)缓冲区没有数据,被调用像缓冲区填充数据(2)缓冲区数据被读完,需要更新时,被调用更新缓冲区数据  public int read()从BufferedReader中读取一个字符  private int read1(char[] cbuf, int off, int len) 将缓冲区中的数据写入到数组cbuf中。off是数组cbuf中的写入起始位置,len是写入长度  String readLine(boolean ignoreLF)读取一行数据。ignoreLF是“是否忽略换行符”  public long skip(long n) 跳过n个字符  public boolean ready()“下一个字符”是否可读  public boolean markSupported()始终返回true。因为BufferedReader支持mark(), reset()  public void mark(int readAheadLimit)标记当前BufferedReader的下一个要读取位置  public void reset() 重置BufferedReader的下一个要读取位置,将其还原到mark()中所保存的位置。  

(3)字符输出流

6.字符数组输出流:charArrayWriter,用于写入字符数据
字段:  protected char buf[];字符数组缓冲   protected int count;下一个字符要写入的位置  构造函数:可以指定缓冲区大小,默认大小是32  public void write(int c),写入一个字符输出流中  public void write(char c[], int off, int len),写入字符数组c到输出流中,off是起始位置,len长度  public CharArrayWriter append(CharSequence csq, int start, int end), 将csq从start位置开始到end结束的数据写入的字符输出输出流  
7.FileWriter:比较简单,不详述
8.PipedWriter:管道输出流,在线程间通信,跟PipedReader配合使用
字段:  private PipedReader sink;与PipedWriter通信的PipedReader对象  private boolean closed = false;管道输出流是否关闭的标记  public PipedWriter(PipedReader snk),构造函数,指定配对的管道输入流  public synchronized void connect(PipedReader snk),将管道输出流和管道输出流进行连接  public void write(int c) ,将字符c写入到管道输出流,并且会将c传输给PipedReader  public synchronized void flush(),清空管道输出流,这里会调用管道输入流的notifyAll(),目的是让输入流放弃当前资源的占有,让其他等待的线程读取PipedWriter的值  public void close(),关闭PipedWriter,关闭之后,会调用receiveLast()通知PipedReader它已经关闭  
9.OutputStreamWriter:将“字节输出流”转换成为“字符输出流”,我们创建“字符输出流对象”时,会指定“字节输出流”以及“字节码”
函数&方法:public OutputStreamWriter(OutputStream out, String charsetName),根据out创建OutputStreamWriter,使用编码charsetName编码  void flushBuffer(),刷新缓冲区  public void write(char cbuf[], int off, int len),将字符输出cbuf从off开始的数据写入到OutputStream中,写入长度len  public void flush(),刷新输出流,它跟flushBuffer()的区别:flushBuffer()只会刷新缓冲,而flush()是刷新流,flush()包括了flushBuffer()  public void close(),关闭输出流  
10.BufferedWriter:缓冲字符输出流,通过字符数组来缓冲数据,当缓冲区满或者用户调用flush()函数时,它会将缓冲区的数据写入到输出流中
字段:  private Writer out;输出流对象  private char cb[];保存“缓冲输出流”数据的字符数组private int nChars, nextChar;nChars是缓冲区中字符的总个数,nextChar是下一个要读取的字符在缓冲区中的位置  private static int defaultCharBufferSize = 8192;默认缓冲区的大小  private String lineSeparator;行分割符  public BufferedWriter(Writer out, int sz),传入writer对象,指定缓冲区大小是sz  private void ensureOpen(),确定字符缓冲区是打开的状态  void flushBuffer(),对缓冲区执行flush操作,将缓冲区的数据写入到Writer中  public void write(int c),将c写入到缓冲区,先转换为字符,写写入缓冲区  public void write(char cbuf[], int off, int len),将字符输出cbuf写入到缓冲中,从cbuf的off位置开始,写入长度len  public void flush(),清空缓冲区数据  

(4)字节输入流

11.FileInputStream文件输入流,通常使用它从某个文件中获得输入字节
FileInputStream(File file)         // 构造函数1:创建“File对象”对应的“文件输入流”FileInputStream(FileDescriptor fd) // 构造函数2:创建“文件描述符”对应的“文件输入流”FileInputStream(String path)       // 构造函数3:创建“文件(路径为path)”对应的“文件输入流”int  available()             // 返回“剩余的可读取的字节数”或者“skip的字节数”void close()                 // 关闭“文件输入流”FileChannel  getChannel()    // 返回“FileChannel”final FileDescriptor getFD() // 返回“文件描述符”int  read()                  // 返回“文件输入流”的下一个字节int  read(byte[] buffer, int byteOffset, int byteCount) // 读取“文件输入流”的数据并存在到buffer,从byteOffset开始存储,存储长度是byteCount。long skip(long byteCount)    // 跳过byteCount个字节  
12.ByteArrayInputStream,字节数组输出流,它包含一个内部缓冲区,该缓冲区包括从流中读取的字节,相当于,它的内部缓冲区是一个字符数组,而ByteArrayInputStream本质就是通过字节数组来实现的
protected byte buf[];保存字节输入流数据的字节数组     protected int pos;下一个会被读取的字节的索引  protected int mark = 0;标记索引  protected int count;字节流的长度  public ByteArrayInputStream(byte buf[]),创建一个内容为buf的字节流  public ByteArrayInputStream(byte buf[], int offset, int length),创建一个内容为buf的字节流,并且从offset开始读取数据,读取的长度是length  public synchronized int read(),读取下一个字节  public synchronized int read(byte b[], int off, int len),将字节流的数据写入到字节数组b中,off是b的开始位置,len是写入长度  public synchronized long skip,跳过n个字符 public synchronized int available(),是否能读取下一个字节  public boolean markSupported(),是否支持标签  public void mark(int readAheadLimit),保存当前位置  public synchronized void reset(),重置索引位置为mark所标记的位置  
13.PipedInputStream,方法同PipedReader,一个操作字符,一个操作字节
14.BufferedInputStream,缓冲输入流

通过一个内部缓冲区数组实现的,例如,在新建某一输入流对应的BufferedInputStream后,通过read()读取数据时,BufferedInputStream会将输入流的数据分批的添加到缓冲区中,每当缓冲区的数据被读取完后,输入流会再次填充缓冲区,直到读取完数据。

private static int defaultBufferSize = 8192;默认缓冲区大小  protected volatile byte buf[];缓冲数组  protected int count;缓冲区中有效字节数,不是指的输入流中有效字节数  protected int pos;缓冲区的位置索引,并不是输入流中的位置索引  protected int markpos = -1;当前缓冲区的位置索引,markpos()和reset()配合使用才有意义。通过mark()函数保存pos的值到markpos中;通过reset()函数将pos的值重置为markpos,接着通过read()读取数据的时候,就会从mark()保存的位置开始读取  protected int marklimit;标记的最大值  private InputStream getInIfOpen(),获取输入流  private byte[] getBufIfOpen(),获取缓冲  public BufferedInputStream(InputStream in),构造函数:新建一个缓冲区大小为8192的BufferedInputStream      public BufferedInputStream(InputStream in, int size) ,指定缓冲区大小  private void fill(),从输入流中读取数据,并填充到缓冲区  public synchronized int read(),读取下一个字节  private int read1(byte[] b, int off, int len),将缓冲区中的数据写入到字节数组b中,off是字节数组b的起始位置,len是长度   public synchronized long skip(long n),忽略N个字符public synchronized int available(),下一个字符是否可以读取  public synchronized void mark(int readlimit),标记缓冲区去当前位置   public synchronized void reset(),重置 public boolean markSupported()是否可标记,永远返回true  
15.ObjectInputStream,对基本数据和对象进行序列化的操作和支持
例举部分:  ObjectInputStream(InputStream input),构造函数  int available()  是否可读byte     readByte()  读取字节int     readInt()  读取Intint     skipBytes(int length)跳过n个字符 
16.DataInputStream,数据输入流,继承FilterInputStream

DataInputStream是用来装饰其他输入流,它“允许应用程序以机器无关方式从底层输入流中读取基本的java数据类型”

public DataInputStream(InputStream in) private byte bytearr[] = new byte[80];  private char chararr[] = new char[80]; public final int read(byte b[]),从数据输入流中读取一个字节  public final int read(byte b[], int off, int len),从数据输入流读取数据,存储到b中,off是字节数字b的起始位置,len是读取字节个数  public final void readFully(byte b[]),从数据输入流中读取数据并填满数组b中,没有填满,数组b就一直读取,直到填满  public final void readFully(byte b[], int off, int len),从数据输入流中读取数据到数组b中,若没有读取len个字节,就一直读取到读取完len个字节位置  public final int skipBytes(int n),跳过n个字节  public final byte readByte() ,读取Byte类型的值   // 从“数据输入流”中读取“无符号的short类型”的值,in.read()返回的int的范围是0-255,也就是8位,我们都知道short是16位,所以读取了两遍,如果读出来的两个数或小于0,说明读取到文件尾,抛出异常;将ch1右移8位,低位取0,低位直接补充ch2,那么便是我们要的无符号short类型public final int readUnsignedShort() throws IOException {     int ch1 = in.read();     int ch2 = in.read();      if ((ch1 | ch2) < 0)          throw new EOFException();      return (ch1 << 8) + (ch2 << 0);  }public final int readInt(),同理在获取int返回值的时候,我们要读取4组数据,然后依次右移取值  public final String readUTF() ,从“数据输入流”中读取"UTF类型"的值  

(5)字节输出流


17.FileOutputStream,文件输出流
FileOutputStream(File file) // 构造函数1:创建“File对象”对应的“文件输入流”;默认“追加模式”是false,即“写到输出的流内容”不是以追加的方式添加到文件中。  FileOutputStream(File file, boolean append) // 构造函数2:创建“File对象”对应的“文件输入流”;指定“追加模式”。  FileOutputStream(FileDescriptor fd)       // 构造函数3:创建“文件描述符”对应的“文件输入流”;默认“追加模式”是false,即“写到输出的流内容”不是以追加的方式添加到文件中。  FileOutputStream(String path)           // 构造函数4:创建“文件(路径为path)”对应的“文件输入流”;默认“追加模式”是false,即“写到输出的流内容”不是以追加的方式添加到文件中。  FileOutputStream(String path, boolean append) // 构造函数5:创建“文件(路径为path)”对应的“文件输入流”;指定“追加模式”。  void  close()      // 关闭“输出流”  FileChannel  getChannel() // 返回“FileChannel”final FileDescriptor getFD()      // 返回“文件描述符”void  write(byte[] buffer, int byteOffset, int byteCount) // 将buffer写入到“文件输出流”中,从buffer的byteOffset开始写,写入长度是byteCount。void  write(int oneByte)  // 写入字节oneByte到“文件输出流”中
18.ByteArrayOutputStream,字节数组输出流
protected byte buf[];,保存“字节数组输出流”的数据的数组  protected int count;字节数组输出流的计数  public ByteArrayOutputStream(),默认字节数组大小,32  public ByteArrayOutputStream(int size),指定字节数组输出流的数组大小  private void ensureCapacity(int minCapacity) ,确认容量,如果实际容量<minCapacity就增加“字节数组输出流”的容量  private void grow(int minCapacity),增加容量  public synchronized void write(int b),写入一个字节到字节数组输出流中  public synchronized void write(byte b[], int off, int len),将b写入到字节数组输出流中,off是b的起始位置,len是写入长度  public synchronized void reset(),重置“字节数组输出流”  public synchronized byte toByteArray()[],将字节数组输出流转换成为字节数组  
19.管道输出流: PipedOutputStream
private PipedInputStream sink;与管道输出流对应的管道输入流  public PipedOutputStream(PipedInputStream snk),指定PipedInputStream  public synchronized void connect(PipedInputStream snk),将管道输出流和输入流进行连接  public void write(int b),将int类型b写入到管道输出流中  public synchronized void flush(),清空“管道输出流”,这里会调用管道输入流的notifyAll(),目的是让管道输入流放弃对当前资源的占用,让其他的等待线程读取输出流中的值  public void close(),关闭管道输出流  
20.BufferedOutputStream ,为一个输出流提供“缓冲功能”
BufferedOutputStream(OutputStream out)BufferedOutputStream(OutputStream out, int size)synchronized void     close()synchronized void     flush()synchronized void     write(byte[] buffer, int offset, int length)synchronized void     write(int oneByte)  
21.ObjectOutputSteam
22.DataOutputSteam,是数据输出流。

它继承于FilterOutputStream,是用来装饰其它输出流,将DataOutputStream和DataInputStream输入流配合使用,“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。

protected int written;"数据输出流"的字节数   private byte[] bytearr = null;“数据输出流”对应的字节数组  public DataOutputStream(OutputStream out)   public synchronized void write(int b) 将int类型的值写入到“数据输出流”中  public synchronized void write(byte b[], int off, int len),将字节数组b从off开始的len个字节,写入到数据输出流中  public void flush(),清空缓冲,将缓冲中的数据都写入的输出流中  // 将short类型的值写入到“数据输出流”中// 注意:short占2个字节public final void writeShort(int v) throws IOException {     // 写入 short高8位 对应的字节     out.write((v >>> 8) & 0xFF); int:32位,右移8位&0Xff那么就取出来了,9-16位做为short的高8位       // 写入 short低8位 对应的字节     out.write((v >>> 0) & 0xFF);左移0位&0ff就将int的0-8位取出,做为short的低8位       incCount(2); }

0 0
原创粉丝点击