一、什么是IO
Java中I/O操作主要是指Java的进行输入,输出操作。Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。
Java的I/O流提供了读写数据的标准方法。人核Java中表示数据源的对象都会提供以数据流的方式读写他的数据方法。
Java.io包几乎包含了所有操作输出、输入需要的类。所有这些类代表了输入源和输出目标。
Java.io包中的流支持很多种格式,比如:基本类型、对象、本地化数字集等等。
一个流可以理解为一个数据的序列。输入流表示一个源读取数据,输出流表示向一个目标写数据。
二、数据流的基本概念
基本流:一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。
输入流:程序从输入流读取数据源。数据源包括外界(键盘、文件、网络....),即是将数据源读入到程序的通信通道。
输出流:程序想输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络....)的通信通道。
采用数据流的目的就是使用输出输入独立于设备。
三、控制台输入和读取
1,控制台输入
Java的控制台输入有System.in完成。
2,控制台输出
控制台输出由print()和println完成。这些方法都由类PrintStream定义,System.out是该类对象的一个引用。
write() 方法不经常使用,因为 print() 和 println() 方法用起来更为方便。
四、I/O体系结构
在真个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.
Java I/O主要包括如下几个层次,包含三个部分:
1,流式部分-IO的主体部分;
2,非流式部分-主要包含一些辅助流式部分的类,如:File类、RandomAccess类和FileDescriptor等类
3,其他类-文件读取部分与安全相关的类。如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。
1,流式部分
java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,java中引入了处理字符的流。
(1)对文件进行操作
FileInputStream(字节输入流),FileOutputStream(字节输出流),FileReader(字符输入流),FileWriter(字符输出流)
a、FileInputStream字节输入流
该流用于从文件读取数据,它的对象可以用new关键字
有多种构造方法可以创建对象
可以使用字符串类型的文件名来创建一个数据流对象来读取文件:
InputStream f = new FileInputStream("C:/java/hello");
也可以使用一个文件对象来从创建一个输入流对象来读取文件。我们得先使用File()方法来创建文件对象,然后创建InputStream对象,就可以使用下面的方法来读取流或者进行其他的操作。
File f = new File("C:/java/hello");
InputStream out = new FileInputStream(f);
常见方法
1、public void close() throws IOException{}
关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
2、protected void finalize()throws IOException {}
这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
3、public int read(int r)throws IOException{}
这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。
4、public int read(byte[] r) throws IOException{}
这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
5、public int available() throws IOException{}
返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。
b、FileOutStream(字节输出流)
该类用来创建一个文件并向文件中写数据。如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建文件。有两个构造方法可以用来创建FileOutputStream对象。
使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("C:/java/hello")
也可以使用一个对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个对象文件对象,创建OutputStream对象完成后,就可以使用下面的方法来写入流或者进行其他的流操作。
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
方法及描述
1、public void close() throws IOException{}
关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
2、protected void finalize()throws IOException {}
这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
3、public void write(int w)throws IOException{}
这个方法把指定的字节写到输出流中。
4、public void write(byte[] w)
把指定数组中w.length长度的字节写到OutputStream中。
c、实例演示
上面的程序首先创建文件test.txt,并且把给定的数字以二进制形式写进该文件,同时输出到控制台上。以上代码由于是二进制写入,可能存在乱码,你可以使用以下代码实例来解决乱码问题:
//文件名 :fileStreamTest2.javaimport java.io.*;
public class fileStreamTest2 { public static void main(String[] args) throws IOException {
File f = new File("a.txt");
FileOutputStream fop = new FileOutputStream(f);
// 构建FileOutputStream对象,文件不存在会自动新建
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
// 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
writer.append("中文输入");
// 写入到缓冲区
writer.append("\r\n");
// 换行
writer.append("English");
// 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
writer.close();
// 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
fop.close();
// 关闭输出流,释放系统资源
FileInputStream fip = new FileInputStream(f);
// 构建FileInputStream对象
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
// 构建InputStreamReader对象,编码与写入相同
StringBuffer sb = new StringBuffer();
while (reader.ready()) { sb.append((char) reader.read());
// 转成char加到StringBuffer对象中 } System.out.println(sb.toString());
reader.close();
// 关闭读取流
fip.close();
// 关闭输入流,释放系统资源
}}
2、对管道进行操作
PipedInputStream(字节输入流),PipedOutputStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)
PipedInputStream的一个实例要和PipedOutputStream的一个实例共同使用,共同完成管道的读取写入操作。主要用于线程操作。
3. 字节/字符数组
ByteArrayInputStream,ByteArrayOutputStream,CharArrayReader,CharArrayWriter是在内存中开辟了一个字节或字符数组。
4. Buffered缓冲流
BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,是带缓冲区的处理流。
缓冲区的作用的主要目的是:避免每次和硬盘打交道,提高数据访问的效率。
5. 转化流
InputStreamReader/OutputStreamWriter,把字节转化成字符。
6. 数据流
DataInputStream,DataOutputStream。
因为平时若是我们输出一个8个字节的long类型或4个字节的float类型,那怎么办呢?
可以一个字节一个字节输出,也可以把转换成字符串输出,但是这样转换费时间,若是直接输出该多好啊,因此这个数据流就解决了我们输出数据类型的困难。
数据流可以直接输出float类型或long类型,提高了数据读写的效率。
7、打印流
printStream,printWriter,一般是打印到控制台,可以进行控制打印的地方。
8、 对象流
ObjectInputStream,ObjectOutputStream,把封装的对象直接输出,而不是一个个在转换成字符串再输出。
9、序列化流
SequenceInputStream。
对象序列化:把对象直接转换成二进制,写入介质中。
【注】
使用对象流需要实现Serializable接口,否则会报错。
而若用transient关键字修饰成员变量,不写入该成员变量,若是引用类型的成员变量为null,值类型的成员变量为0.
2、非流式部分主要类
File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件,判断文件所在路径等。
RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作
a、File类
在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。
但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。
作用:File类主要用于命名文件、查询文件属性和处理文件目录。
共提供了四个不同的构造函数,以不同的参数形式灵活地接受文件和目录名信息。
1)File(String pathname)
File f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
2)File(URL uri)
通过将给定的file:URI转换成一个抽象路径名来创建一个新的File实例。
3)File(String parent,String child)
根据parent路径名字符串和child路径名字符串创建一个新的File实例。
// 注意:D:\\dir1目录事先必须存在,否则异常
File f2=new File(“D:\\dir1","FileTest2.txt");
4)File(File parent ,String child)
通过给定的父抽象路径名和子路径名字符串创建一个新的File实例。
File f4=newFile("E:\\dir3");
File f5=newFile(f4,"FileTest5.txt");//在如果 E:\\dir3目录不存在则需要先使用f4.mkdir()先创建
5)方法及描述
1 public String getName()
返回由此抽象路径名表示的文件或目录的名称。
2 public String getPath()
将此抽象路径名转换为一个路径名字符串。
3 public String getAbsolutePath()
返回抽象路径名的绝对路径名字符串。
4 public boolean exists()
测试此抽象路径名表示的文件或目录是否存在。
5 public boolean isDirectory()
测试此抽象路径名表示的文件是否是一个目录。
6 public boolean isFile()
测试此抽象路径名表示的文件是否是一个标准文件。
7 public long length()
返回由此抽象路径名表示的文件的长度。
8 public boolean delete()
删除此抽象路径名表示的文件或目录。
9 public String[] list()
返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。
10 public File[] listFiles()
返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
11 public boolean mkdir()
创建此抽象路径名指定的目录。
12 public boolean mkdirs()
创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。
13 public boolean renameTo(File dest)
重新命名此抽象路径名表示的文件。
14 public boolean equals(Object obj)
测试此抽象路径名与给定对象是否相等。
15 public String toString()
返回此抽象路径名的路径名字符串。
6)实例,输出一个目录中的所有文件名(目录可能是多级目录,如a目录中有b、c目录。。。)
五. Java IO 的一般使用原则
一)按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二)按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三)按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四)按数据格式分:
1 、二进制格式(只要不能确定是纯文本的,比如图片、音频、视频) : InputStream, OutputStream 及其所有带 Stream 结尾的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类
五)按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类
六)特殊需要:
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
六、实例
1. 过滤文件后缀名
有时需要列出目录下指定类型的文件,例如:. java、. txt 等扩展名的文件。
【例】找出“e:/aa”下的所有 .java 文件
2. 从键盘输入、输出到显示器
3. 从键盘输入到文件
4. 从文件读入,输出到显示器
5. 从一个文件读入到另一个文件(文件复制)
转载自:https://blog.csdn.net/qq_41573234/article/details/83689856