从零开始学java(28)

Day18

今天主要学习java中的IO体系。对其中5个类File、OutputStream、InputStream、Writer、Reader有初步了解。
常识:标准输入设备是键盘,标准输出设备是显示器。

Java IO中常用的类

在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了
从零开始学java(28) 1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
4.Reader(文件格式操作):抽象类,基于字符的输入操作。
5. Writer(文件格式操作):抽象类,基于字符的输出操作。
6. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
从零开始学java(28)
java I/O主要包括如下几个层次,包含三个部分:

1.流式部分――IO的主体部分;

2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

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

1.File:

表示文件或目录(文件夹),提供的方法,可以文件进行:创建,删除,获取信息,得到子目录中的文件,判断文件所在路径等;注意不能操作文件的内容。

一些常用的API:
boolean createNewFile()当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

boolean delete()删除此抽象路径名表示的文件或目录。//注意:这个删除,不走回收站,直接删除,所以要小心使用。

boolean exists()测试此抽象路径名表示的文件或目录是否存在。

File getAbsoluteFile()返回此抽象路径名的绝对路径名形式。

String getAbsolutePath()返回此抽象路径名的绝对路径名字符串。

String getName()返回由此抽象路径名表示的文件或目录的名称。

String getParent()返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。

File getParentFile()返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。

String getPath()将此抽象路径名转换为一个路径名字符串。

boolean isDirectory()测试此抽象路径名表示的文件是否是一个目录。

boolean isFile()测试此抽象路径名表示的文件是否是一个标准文件。

long length()返回由此抽象路径名表示的文件的长度。字节数

String[] list()返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。//遍历目录返回的只有名字

File[] listFiles()返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。//返回路径全名 推荐

File[] listFiles(FileFilter filter)返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。

File[] listFiles(FilenameFilter filter)返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。

static File[] listRoots()列出可用的文件系统根。

boolean mkdir()创建此抽象路径名指定的目录。调用该方法时,File对象必须对应一个路径,而不是文件 //只能创建一个目录

boolean mkdirs()创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 //即可创建一个目录,也可创建多及目录,推荐

2.流式部分

1.流的概念和作用

流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。
流的本质:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

流的作用:为数据源和目的地建立一个输送通道。

Java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流。

2.IO流的分类:

1.根据操作的数据类型的不同可以分为 :字节流与字符流。

流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。

字节流:数据流中最小的数据单元是字节
InputStream(FileInputStream),OutputStrram(FileInputStream)

字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
Reader(BufferedReader),Writer(BufferedWriter)

2.根据数据的流向分为:输入流与输出流,程序(内存)作为参照物,程序从外部读取称为输入(Input),程序向外部写数据成为输出(Output)。

采用数据流的目的就是使得输出输入独立于设备。
输入流( Input Stream )不关心数据源来自何种设备(键盘,文件,网络)。
输出流( Output Stream )不关心数据的目的是何种设备(键盘,文件,网络)。

特点: 相对于程序来说,输出流是往存储介质或数据通道写入数据,而输入流是从存储介质或数据通道中读取数据,一般来说关于流的特性有下面几点:

1.先进先出,最先写入输出流的数据最先被输入流读取到。

2.顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作)

3.只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

3.Java IO流对象

1.输入字节流InputStream

1.InputStream是所有的输入字节流的父类,它是一个抽象类。

2.ByteArrayInputStream、StringBufferInputStream(StreamBufferInputStream)、FileInputStream是三种基本的介质流,它们分别从Byte数组、StringBuffer、和本地文件中读取数据。

3.PipedInputStream是从与其它线程共用的管道中读取数据.

4.ObjectInputStream和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。

InputStream中的三个基本的读方法:

1.abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。

2.int read(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。

3.int read(byte[] b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

流结束的判断:方法read()的返回值为-1时。
void close() :关闭输入流,释放和这个流相关的系统资源。

2.输出字节流OutputStream

1.OutputStream是所有的输出字节流的父类,它是一个抽象类。

2.ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据。PipedOutputStream是向与其它线程共用的管道中写入数据。

3.ObjectOutputStream和所有FilterOutputStream的子类都是装饰流。

outputStream中的三个基本的写入方法
1.abstract void write(int b):往输出流中写入一个字节。

2.void write(byte[] b) :往输出流中写入数组b中的所有字节。
3.void write(byte[] b, int off, int len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。

void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
void close() :关闭输出流,释放和这个流相关的系统资源。

3.字符输入流Reader

1.Reader是所有的输入字符流的父类,它是一个抽象类。

2.CharReader、StringReader是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedReader是从与其它线程共用的管道中读取数据。

3.BufferedReader是一个装饰器,它和其子类负责装饰其它Reader对象。

4.FilterReader是所有自定义具体装饰流的父类,其子类PushbackReader对Reader对象进行装饰,会增加一个行号。

5.InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader的方法。Reader中各个类的用途和使用方法基本和InputStream中的类使用一致。

主要方法
1.public int read();:读取一个字符,返回值为读取的字符

2.public int read(char cbuf[ ]);:读取一系列字符到数组cbuf[ ]中,返回值为实际读取的字符的数量。

3.public abstract int read(char cbuf[ ],int off,int len) ;:读取len个字符,从数组cbuf[ ]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现。

流结束的判断:方法readLine()的返回值为null时。

4.字符输出流Writer

1.Writer是所有的输出字符流的父类,它是一个抽象类。

2.CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char数组、String中写入数据。PipedWriter是向与其它线程共用的管道中写入数据,

3.BufferedWriter是一个装饰器为Writer提供缓冲功能。

4.PrintWriter和PrintStream极其类似,功能和使用也非常相似。

5.OutputStreamWriter是OutputStream到Writer转换的桥梁,它的子类FileWriter其实就是一个实现此功能的具体类。功能和使用和OutputStream极其类似。

主要方法:

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个字符写入输出流

4.字节流和字符流的区别

字节流和字符流的区别:
输出方式不同:字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

所以,只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。

以上部分参考自深入理解Java中的IO,想要了解更多的朋友可以参考。