java 中的io

来源:互联网 发布:义隆单片机 图书 编辑:程序博客网 时间:2024/05/20 11:35
 Java中对于IO操作拥有的类有很多,很容易记混淆,需要读者认真梳理,这样才能使用的顺手,不至于出太大的错误。本篇博客将对Java中涉及到的所有IO操作,做一次总结,帮助各位去梳理一下看似混乱的IO操作方法。此外,如果之前阅读过博客《OkHttp深入学习(四)——0kio》http://blog.csdn.net/evan_man/article/details/51204469,可以跟本篇博客进行对比,了解okio的优势所在。
    Java中的IO操作大体分为如下四类:
  • InputStream :
    • 该类用于读取字节流数据,往下大体又分为如下四类:
    • FileInputStream、ObjectInputStream、FilterInputStream(BufferedInputStream)
  • OutputStream :
    • 该类用于写入字节流数据,往下大体又分为如下四类:
    • FileOutputStream、ObjectOutputStream、FilterOutputStream(BufferedOutputStream) 
  • Reader
    • 该类用于读取字符流数据,往下大体又分为如下两类:
    • InputStreamReader(FileReader)、BufferedReader
  • Writer
    • 该类用于写入字符流数据,往下大体又分为如下三类:
    • OutputStreamWriter(FileWriter)、BufferedWriter、PrintWriter 
    下面我们将对上述的内容进行详细的介绍。介绍完四类基本IO操作后对于经常使用的System.in、System.out、Scanner以及文件File操作进行详细介绍。文末是一个对本文的而一个简单总结。


PartA 读写字节(最原始)


InputStream

继承关系:
public abstract class InputStream  extends Object  implements Closeable
是一个抽象类,声明了一个read()抽象方法,该方法读取一个字节并返回读取到的字节值;同时该方法会发生阻塞行为,知道有字节流可读则返回;
包含方法:
abstract int read();
    该方法返回一个0到255的比特值,如果没有比特数据可以读取返回-1;该方法会造成线程阻塞。
int available();
int read(byte[] b);
int read(byte[] b, int off, int len);
void close();
   
著名的子类:
  • FileInputStream
    • 继承关系:public class FileInputStream  extends InputStream
    • 构造器:constructors:
      • FileInputStream(File file);根据File对象打开一个文件的输入连接
      • FileInputStream(String name);根据文件路径打开一个对应文件的输入连接
    • 功能
      • 用于对文件内容进行二进制读取,如视频、图片、声音等文本内容
  • ObjectInputStream
    • 继承关系:public class ObjectInputStream  extends InputStream implements ObjectInput, ObjectStreamConstants
    • 构造器:constructors:
      • ObjectInputStream(InputStream in);从一个特定的InputStream流中创建一个ObjectInputStream对象
    • 功能
      • 通过readObject方法反序列化出InputStream对应的对象
      • readObject() ;Read an object from the ObjectInputStream.
      • readxx(); 读取基本数据类型,如readInt();
  • BufferedInputStream
    • 继承关系:public class BufferedInputStream  extends FilterInputStream
    • 构造器:constructors:
      • BufferedInputStream(InputStream in) ;使用默认缓存大小
      • BufferedInputStream(InputStream in, int size) ;使用特定缓存大小
    • 功能
      • 减少IO访问次数,一次读取多个字节的数据

OutputStream

继承关系:
public abstract class OutputStream  extends Object implements Closeable, Flushable
是一个抽象类,声明了一个write(int)抽象方法,该方法向输出流中写入一个字节的数据;
包含方法:
abstract void write(int b);
    写入一个比特输入到输出流中,对于参数b的高24位自动忽略。
void write(byte[] b)
    Writes b.length bytes from the specified byte array to this output stream.
void write(byte[] b, int off, int len)
    Writes len bytes from the specified byte array starting at offset off to this output stream.
void flush()
    Flushes this output stream and forces any buffered output bytes to be written out.
void close()
    Closes this output stream and releases any system resources associated with this stream.
    
著名的子类:
  • FileOutputStream
    • 继承关系:public class FileOutputStream  extends OutputStream
    • 构造器:constructors:
      • FileOutputStream(File file);
      • FileOutputStream(File file, boolean append) ;
        • 根据一个File对象,创建一个FileOutputStream流,第二个参数为true表示写入的其实位置位于文本的末尾。否则从文本的起始位置写入新信息。
      • FileOutputStream(String name) ;
      • FileOutputStream(String name, boolean append)
        • 根据一个FilePath地址,创建一个FileOutputStream流,第二个参数为true表示写入的其实位置位于文本的末尾。否则从文本的起始位置写入新信息。
    • 功能
      • 对文本的二进制原始数据的写入
  • ObjectOutputStream
    • 继承关系:public class ObjectOutputStream  extends OutputStream implements ObjectOutput, ObjectStreamConstants
    • 构造器:constructors:
      • ObjectOutputStream(OutputStream out) ;Creates an ObjectOutputStream that writes to the specified OutputStream.
    • 功能
      • 通过writeObject方法序列化对象到ObjectOutputStream绑定的输出流中
      • void writeObject(Object obj) ;Write the specified object to the ObjectOutputStream.
      • writexx(); 读取基本数据类型,如writeInt();
  • BufferedOutputStream
    • 继承关系:public class BufferedOutputStream  extends FilterOutputStream
    • 构造器:constructors:
      • BufferedOutputStream(OutputStream out) ;使用默认缓存大小
      • BufferedOutputStream(OutputStream out, int size) ;使用指定缓存大小
    • 功能
      • 减少IO访问次数,一次写入多个字节的数据



PartB  读写字符(Unicode文本)(多个字节流一起读)

Reader

继承关系:
public abstract class Reader  extends Object implements Readable, Closeable
是一个抽象类,声明了一个 read(char[] cbuf, int off, int len) 抽象方法,从流中读取字符到数组中;
包含方法:
int read()
    读取一个单字符
abstract int read(char[] cbuf, int off, int len)
    Reads characters into a portion of an array.
abstract void close()
    Closes the stream and releases any system resources associated with it.
著名的子类:
Direct Known Subclasses
  • InputStreamReader
    • 继承关系:public class InputStreamReader  extends Reader
    • 构造器:constructors:
      • InputStreamReader(InputStream in) ;创建一个InputStreamReader使用默认的字符集.
      • InputStreamReader(InputStream in, Charset cs) ;
      • InputStreamReader(InputStream in, CharsetDecoder dec) ;
      • InputStreamReader(InputStream in, String charsetName) ;
        • 创建一个InputStreamReader使用特定的字符集
    • 功能
      • 是比特流到字符流之前的桥梁,读取字符流数据然后解码成对应的字符
  • BufferedReader
    • 继承关系:public class BufferedReader  extends Reader
    • 构造器:constructors:
      • BufferedReader(Reader in) ;Creates a buffering character-input stream that uses a default-sized input buffer.
      • BufferedReader(Reader in, int sz) ;Creates a buffering character-input stream that uses an input buffer of the specified size.
    • 功能
      • 提供了一个缓存的功能
  • FileReader(使用默认的编解码,使用默认大小的缓存,故应该不建议使用)
    • 继承关系:public class FileReader  extends InputStreamReader
    • 构造器:constructors:
      • FileReader(File file) ;Creates a new FileReader, given the File to read from.
      • FileReader(String fileName) ;Creates a new FileReader, given the name of the file to read from.
    • 功能
      • 方便与对文件中的字节流数据进行字符方式读取,使用默认的字符集和默认的缓存大小。

Writer

继承关系:
public abstract class Writer  extends Object implements Appendable, Closeable, Flushable
是一个抽象类,声明了一个 write(char[] cbuf, int off, int len)抽象方法,向流中写入部分字符;
包含方法:
void write(int c)
    写入一个单字符
abstract void write(char[] cbuf, int off, int len)
    Writes a portion of an array of characters.
Writer append(char c)
    Appends the specified character to this writer.
Writer append(CharSequence csq)
    Appends the specified character sequence to this writer.
Writer append(CharSequence csq, int start, int end)
    Appends a subsequence of the specified character sequence to this writer.
abstract void close()
    Closes the stream, flushing it first.
abstract void flush()
    Flushes the stream.
著名的子类:
  •  OutputStreamWriter
    • 继承关系:public class OutputStreamWriter  extends Writer
    • 构造器:constructors:
      • OutputStreamWriter(OutputStream out) ;创建一个OutputStreamWriter使用默认的字符集.
      • OutputStreamWriter(OutputStream out, Charset cs) ;
      • OutputStreamWriter(OutputStream out, CharsetEncoder enc) ;
      • OutputStreamWriter(OutputStream out, String charsetName) ;
        • 创建一个OutputStreamWriter使用特定的字符集
    • 功能
      • 是比特流到字符流之前的桥梁,对字符进行编码然后以二进制格式存入输出流中
  • BufferedWriter
    • 继承关系:public class BufferedWriter  extends Writer
    • 构造器:constructors:
      • BufferedWriter(Writer out) ;Creates a buffered character-output stream that uses a default-sized output buffer. 
      • BufferedWriter(Writer out, int sz) ;Creates a new buffered character-output stream that uses an output buffer of the given size.
    • 功能
      • 提供了一个缓存的功能
  • PrintWriter(用于以文本格式打印字符串和数字的方法,就是我们习惯的println、printf等)
    • 继承关系:public class PrintWriter  extends Writer
    • 构造器:constructors:(支持了所有的类型,构造该对象
      • PrintWriter(File file) ;Creates a new PrintWriter, without automatic line flushing, with the specified file. 
      • PrintWriter(File file, String csn) ;Creates a new PrintWriter, without automatic line flushing, with the specified file and charset. 
      • PrintWriter(OutputStream out) ;Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream. 
      • PrintWriter(OutputStream out, boolean autoFlush) ;Creates a new PrintWriter from an existing OutputStream. 
      • PrintWriter(String fileName) ;Creates a new PrintWriter, without automatic line flushing, with the specified file name. 
      • PrintWriter(String fileName, String csn) ;Creates a new PrintWriter, without automatic line flushing, with the specified file name and charset. 
      • PrintWriter(Writer out) ;Creates a new PrintWriter, without automatic line flushing. 
      • PrintWriter(Writer out, boolean autoFlush) ;Creates a new PrintWriter.
    • 功能
      • 提供大量的写入字符数据的接口,我们大部分情况都是使用的这个类进行写入操作,同时System.out就是一个PrintWriter对象


PartC System.in&&System.out&&Scanner

System.in

System类中in属性定义如下:public final static InputStream in = null; in对应一个InputStream类型对象,提供常用二进制流文件访问方法。in属性的初始化是由系统完成的,一般用于接收键盘或者用户环境特定的输入源。

System.out

System类中out属性定义如下:public final static PrintStream out = null; out对应一个PrintStream类型对象,PrintStream内部有一个BufferdWriter对象,具体的操作都是通过该对象完成的!print方法利用String.valueOf方法将数据转换为String类型的数据;随后BufferWriter调用writ(String str)方法。out属性的初始化是由系统完成的,一般对应于用户的显示屏设备或者其它用户环境输出。

Scanner

  • 继承关系:public final class Scanner extends Object implements Iterator<String>, Closeable
  • 构造器:constructors:
    • Scanner(File source, String charsetName) ;Constructs a new Scanner that produces values scanned from the specified file. 
    • Scanner(InputStream source, String charsetName) ;Constructs a new Scanner that produces values scanned from the specified input stream. 
    • Scanner(Path source, String charsetName) ;Constructs a new Scanner that produces values scanned from the specified file. 
    • Scanner(Readable source) ;Constructs a new Scanner that produces values scanned from the specified source. 
    • Scanner(String source) ;Constructs a new Scanner that produces values scanned from the specified string.
  • 功能
    • A simple text scanner which can parse primitive types and strings using regular expressions.
    • 使用正则表达式,来读取一串流数据;对任意数据进行读取操作,对应的有PrintWriter!
    • 默认使用空格符做给分隔符;也可以定制分隔符s.useDelimiter(" |,|\\.")
    • next方法以当前非空字符开始,到空字符出现截止为一个数据;(空字符被去掉)
      • nextxx()等价于xx var = Xx.valueOf(next());  xx是基本数据类型Xx为对应的类,如int与Integer,long与Long
    • nextline以当前字符开始到\n换行符出现截止为下一个数据;(换行符不在读取的string里面)
    • 注意:Scanner读取数据采用的原理使用的是分隔符;每一个nextXX使用的分隔符也是不一样的;如nextLine和nextInt分隔符肯定不一样;所以为了避免这样的问题,建议:使用hasNextXX()判断是否存在对应类型数据,就使用对应的nextXX()取数据!



PartD 文件操作

PATH 

继承关系:
public interface Path  extends Comparable<Path>, Iterable<Path>, Watchable
是一个抽象类,声明了一系列对文件路径的操作(可以是目录也可以是文件的路径)
包含方法:
Path toAbsolutePath()
    绝对路径
File toFile()
    根据路径得到File对象

Path resolve(Path other)
Path resolve(String other)
  • 若为绝对路径则返回绝对路径,若不是则由this+other共同组成新的路径

Path resolveSibling(Path other)
Path resolveSibling(String other)
  • 将参数的path合并到调用该方法的path的父路径下

Path getParent()
    返回父路径或者null
Path getRoot()
    返回根路径或者null
Path getFileName()
    获取文件名字


Paths

该类主要使用它的get方法获得一个Path对象
public static Path get(String first,  String... more)
    将一串字符串,利用系统的分隔符组合成一个新的string作为该系统下的文件路径,返回Path 
    

Files 

继承关系:
public final class Files  extends Object
是一个final类,声明了一系列public static方法;大部分方法接收的参数为Path类型对象, 然后做相关处理;
包含方法:
static long size(Path path)
    Returns the size of a file (in bytes).

//获取输入输出流
static InputStream newInputStream(Path path, OpenOption... options)
    Opens a file, returning an input stream to read from the file.
static OutputStream newOutputStream(Path path, OpenOption... options)
    Opens or creates a file, returning an output stream that may be used to write bytes to the file.
static BufferedReader newBufferedReader(Path path, Charset cs)
    Opens a file for reading, returning a BufferedReader that may be used to read text from the file in an efficient manner.
static BufferedWriter newBufferedWriter(Path path, Charset cs, OpenOption... options)
    Opens or creates a file for writing, returning a BufferedWriter that may be used to write text to the file in an efficient manner.

//文件的输入输出流
static Path move(Path source, Path target, CopyOption... options)
    Move or rename a file to a target file.
static boolean deleteIfExists(Path path)
    Deletes a file if it exists.
static Path copy(Path source, Path target, CopyOption... options)
    Copy a file to a target file.

//创建目录和文件
static Path createDirectories(Path dir, FileAttribute<?>... attrs)
    Creates a directory by creating all nonexistent parent directories first.(自动创建路径中没有的目录)
static Path createFile(Path path, FileAttribute<?>... attrs)
    Creates a new and empty file, failing if the file already exists.

//创建临时目录和文件
static Path createTempDirectory(Path dir, String prefix, FileAttribute<?>... attrs)
    Creates a new directory in the specified directory, using the given prefix to generate its name.
static Path createTempDirectory(String prefix, FileAttribute<?>... attrs)
    Creates a new directory in the default temporary-file directory, using the given prefix to generate its name.
static Path createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>... attrs)
    Creates a new empty file in the specified directoryusing the given prefix and suffix strings to generate its name.
static Path createTempFile(String prefix, String suffix, FileAttribute<?>... attrs)
    Creates a new empty file in the default temporary-file directoryusing the given prefix and suffix to generate its name.

//判断是Path所指的是文件还是目录
  • Files.isDirectory(myPath);

//遍历一个Path下的所有路径(类似一级路径)
  • DirectoryStream<Path> entries = Files.newDirectoryStream(myPath);

//遍历一个Path下的所有子孙路径(遍历所有文件)
  • Path walkPath = Files.walkFileTree(myPath, new SimpleFileVisitor<Path>(){ ...@override若干方法... };

PartE 补充

接口

  • public interface  Appendable, Closeable, Flushable,Readable接口
    • 分别拥有append、close、flush、read方法
  • public interface  CharSequence接口,描述了一个char值序列的基本属性,有名子类CharBuffer, Segment, String, StringBuffer, StringBuilder
    • 拥有charAt(),length(),subSequence(),toString方法
  • public interface DataOutput
    • 定义了writeXX(); XX为基本数据类型
  • public interface DataInput
    • 定义了readXX(); XX为基本数据类型

etc:

  • RandomAccessFile (是一类可以在文件任意位置进行读取操作的类)
  • ZipInputStream和ZipOutPutStream负责对ZIP文件进行处理,ZIP内部就是一个文件系统


总结

PartA

数据的起点都是二进制数据,即都是InputSteam和OutputStream的子类,这样的子类有名的有FileInputStream、FileOutputStream;
FileInputStream、FileOutputStream两者的构造器接受的参数为两种,一为File、二为String代表文件路径;
通过上面步骤我们获得了一个InputSteam或OutputStream对象,通过最原始的read、write方法或者read(byte[] b, int off, int len)、write(byte[] b, int off, int len)方法读写特定字节数的数据;
当然我们可以对上面的最原始的流进行包装再使用;
  • 使用BufferedInputStream和BufferedOutputStream进行包装,两者的构造器参数为InputStream或OutputStream对象,使用方式同普通的InputSteam和OutputStream一样,只是底层实现了缓存效率会高很多。
  • 使用ObjectInput和ObjectOutput进行包装,两者的构造器参数为InputStream或OutputStream对象,随后调用readObject、readXX、writeObject、writeXX的方法对java对象进行读写,其实就是一个二进制流和一个Object之间的转换;
  • 使用InputStreamReader和OutputStreamReader进行包装,两者构造器参数为InputStream或OutputStream对象和charset,随后调用read(char[] cbuf, int off, int len)、write(char[] cbuf, int off, int len)方法读写特定数目的字符,其实这是一个二进制流和字符之间的转换,使用的编解码器,可以使用系统默认,也可以在构造对象的时候进行指明;
    • 对于Reader和Writer对象,还可以使用BufferedReader和BufferedWriter进行包装,使得后面的读写操作更加高效;底层实现其实就是一次性读取一块数据出来,缓存在一个地方,随后程序读取数据不是直接从硬盘中的文件中读取,而是从之前缓存的数据块中取,当数据快取完的时候,BufferedReader会再从硬盘文件中读取一整块数据;

PartB

对于Java中文件的操作,首先需要通过Paths的静态方法——get(String)、get(URI)获取到Path,;或者通过Path的resolve(String)和resolveSibling(String) 方法获取到Path;随后利用final Class Files进行一般的文件操作,如删除复制移动,获取输入输出流等;
此外上面的Path类还有一些很有用的方法,能对路径进行相关解析;
Files除了完成基本的文件操作,还完成了如创建临时文件夹和临时文件等操作;

PartC

正则表达式——一串特定格式的字符串,用于判断一个String对象是否满足这个规则。
原创粉丝点击