前言
这个是个人在学习Java的IO流知识时所记录的笔记,涉及IO流的基础知识;
1. File类
1.1 File类基本概念
- File类的一个对象,代表一个文件或一个文件目录;
- File类声明在java.io包下;
- 创建实例的三种方式:
- File(String filePath)
①相对路径:相较于某个路径下指明的路径
②绝对路径:包含盘符在内的文件或文件目录的路径
- File(String parentPath, String childPath)
- File(File parentPath, String childPath)
- File类的对象常会作为参数传递到流的构造器中,指明读取或写入的终点;
注意:涉及读取或写入文件内容必须使用IO流来完成;
1.2 File类常用方法
获取功能:
String getAbsolutePath()
:获取绝对路径
String getPath()
:获取路径
String getName()
:获取名称
String getParent()
:获取上层文件目录路径,若没有就返回null
Long length()
:获取文件长度,不能获取目录的长度
Long lastModified()
:获取最后一次的修改时间(ms)
String[] list()
:获取指定目录下的所有文件或文件目录的名称数组
File[] listFiles()
:获取指定目录下的所有文件或文件目录的File数组
重命名功能:
boolean renameTo(File dest)
:把文件重命名为指定的文件路径
1 2
| Boolean renameTo = file1.renameTo(file2)
|
判断功能:
boolean isDirectory()
:判断是否是文件目录
boolean isFile()
:判断是否是文件
boolean exists()
:判断是否存在
boolean canRead()
:判断是否可读
boolean canWrite()
:判断是否可写
boolean isHidden()
:判断是否隐藏
创建和删除功能:
boolean createNewFile()
:创建文件,若文件已存在返回false
boolean mkdir()
:创建文件目录,上层目录不存在就不创建
boolean mkdirs()
:创建文件目录,上层目录不存在就一并创建
boolean delete()
:删除文件或文件夹
2. 节点流(文件流)
注意:字符流不能用来处理图片等字节数据,处理字节数据要用字节流;
总结:字节流和字符流的读写操作基本步骤一致,都是分为4步;
2.1 字节流
FileInputStream读取非文本文件基本操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 1.实例化File类的对象,指明要操作的文件: File file = new File(String filePath);
2.FileInputStream流的实例化,提供具体的流: FileInputStream fis = new FileInputStream(file);
3.数据的读入操作 byte[] buffer = new byte[int]; int len; while ((len = fr.read(buffer)) != -1) { String str = new String(buffer, 0, len); System.out.print(str); }
4.流的关闭操作 if (fis != null) { fis.close( ); }
1.对于文本文件(.txt, .java, .c, .cpp等)建议使用字符流处理,字节流处理可能出现乱码; 2.对于非文本文件(图片、视频等)必须使用字节流处理;
|
2.1.2 字节输出流:FileOutputStream
使用FileInputStream和FileOutputStream实现非文本文件的复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 1.实例化File类的对象,指明读入和写出的文件: File srcFile = new File(String filePath); File destFile = new File(String filePath);
2.创建输入流和输出流的对象: FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile);
3.数据的读入和写出操作 (复制过程) byte[] buffer = new byte[int];
int len = fis.read(buffer); while (len != -1) { fos.write(buffer, 0, len); }
4.流资源的关闭操作 if (fis != null) { fis.close( ); } if (fos != null) { fos.close( ); }
|
2.2 字符流
2.2.1 字符输入流:FileReader
FileReader读入数据基本操作步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 1.实例化File类的对象,指明要操作的文件: FileReader fr = null; File file = new File(String filePath);
2.Filereader流的实例化,提供具体的流: fr = new FileReader(file);
3.数据的读入操作 int data = fr.read( ); while (data != -1) { System.out.println((char)data); data = fr.read(); }
4.流的关闭操作 if (fr != null) { fr.close( ); }
|
使用read的重载方法read(char[ ] cbuf)
进行读入操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| char[] cbuf = new char[int]; int len = fr.read(cbuf); while (len != -1) { for (int i=0; i<len; i++) { System.out.print(cbuf[i]); } String str = new String(cbuf, 0, len); System.out.print(str); }
|
2.2.2 字符输出流:FileWriter
FileWriter写出数据基本操作步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 1.实例化File类的对象,指明写出到的文件: FileWriter fw = null; File file = new File(String filePath);
2.FileWriter流的实例化,用于数据写出: fw = new FileWriter(file);
3.数据的写出操作 fw.write("String");
4.流资源的关闭操作 if (fw != null) { fw.close( ); }
1.输出操作,对应的File如果不存在,在输出的过程中会自动创建此文件; 2.对应的File如果存在,根据构造器不同: FileWriter fw = new FileWriter(file)会对原有文件进行覆盖 FileWriter fw = new FileWriter(file, true)不会对原有文件进行覆盖,而是在原有文件基础上追加内容
|
使用FileReader和FileWriter实现文本文件的复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 1.实例化File类的对象,指明读入和写出的文件: File srcFile = new File(String filePath); File destFile = new File(String filePath);
2.创建输入流和输出流的对象: FileReader fr = new FileReader(srcFile); FileWriter fw = new FileWriter(destFile);
3.数据的读入和写出操作 (复制过程) char[] cbuf = new char[int];
int len = fr.read(cbuf); while (len != -1) { fw.write(cbuf, 0, len); }
4.流资源的关闭操作 if (fr != null) { fr.close( ); } if (fw != null) { fw.close( ); }
|
3. 处理流
3.1 缓冲流
作用:内部提供了一个缓冲区,提高流的读取和写入的速度;(因此缓冲流读写速度快于文件流)
3.1.1 字节型
作用在InputStream上:BufferedInputStream
作用在OutputStream上:BufferedOutputStream
使用BufferedInputStream和BufferedOutputStream实现非文本文件复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 1.实例化File类的对象,指明读入和写出的文件:(造文件) File srcFile = new File(String filePath); File destFile = new File(String filePath);
2.创建输入流和输出流的对象:(造流)
FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileInputStream(destFile);
BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos);
3.数据的读入和写出操作 :(复制过程) byte[] buffer = new byte[int]; int len; while ((len = bis.read(buffer)) != -1) { bos.write(buffer, 0, len); }
4.流资源的关闭操作
bos.close( ); bis.close( );
fos.close( ); fis.close( );
|
3.1.2 字符型
作用在FileReader上:BufferedReader
作用在FileWriter上:BufferedWriter
使用BufferedReader和BufferedWriter实现文本文件复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 1.实例化File类的对象,指明读入和写出的文件:(造文件) File srcFile = new File(String filePath); File destFile = new File(String filePath);
2.创建输入流和输出流的对象:(造流)
FileReader fr = new FileReader(srcFile); FileWriter fw = new FileWriter(destFile);
BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw);
3.数据的读入和写出操作 :(复制过程) char[] cbuf = new char[int]; int len; while ((len = br.read(cbuf)) != -1) { bw.write(cbuf, 0, len); }
4.流资源的关闭操作
br.close( ); bw.close( );
|
3.2 转换流
作用:提供了在字节流和字符流之间的转换,本身属于字符流;
将一个字节的输入流转换为字符的输入流(解码):InputStreamReader
1 2 3 4 5 6 7 8 9 10 11 12 13
| FileInputStream fis = new FileInputStream(new File(String filepath));
InputStreamReader isr = new InputStreamReader(fis, "UTF-8")
char[] cbuf = new char[int]; int len; while ((len = isr.read(cbuf)) != -1) { System.out.print(new String(cbuf, 0, len)); }
isr.close();
|
将一个字符的输出流转换为字节的输出流(编码):OutputStreamWriter
切换字符集实现文件读入与写出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| FileInputStream fis = new FileInputStream(new File(String path)); FileOutputStream fos = new FileOutputStream(new File(String path));
InputStreamReader isr = new InputStreamReader(fis, "UTF-8")
OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk")
char[] cbuf = new char[int]; int len; while ((len = isr.read(cbuf)) != -1) { osw.write(cbuf, 0, len); }
isr.close(); osw.close();
|
3.3 对象流
作用:用于存储和读取基本数据类型数据或对象的处理流,可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来;
对象序列化机制:允许把内存中任何实现了Serializable接口的对象转换成与平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象;
ObjectOutputStream序列化:对象写入到数据源
1 2 3 4 5 6 7 8 9 10 11
| 1.造文件、造节点流和处理流 File file =new File("object.data") ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))
2.写出对象 oos.writeObject(new String("a example"));
oos.flush( );
3.关闭流资源 oos.close( );
|
ObjectInputStream反序列化:从数据源还原对象
1 2 3 4 5 6 7 8 9 10 11 12
|
1.造文件、造节点流和处理流 File file =new File("object.data") ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))
2.读取对象 String str = (String) ois.readObject( ); System.out.println(str);
3.关闭流资源 ois.close( );
|
注意:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
3.4 其他流
3.4.1 标准输入流、输出流
3.4.2 打印流
作用:将基本数据类型的数据格式转化为字符串输出;
- 字节输出流:PrintStream
- 字符输出流:PrintWriter
3.4.3 数据流
作用:用于读取或写出基本数据类型的变量或字符串;
- DateInputStream:将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中
- DateOutputStream:将内存中的字符串、基本数据类型的变量写出到文件中
注意:读取不同类型的数据的顺序要与当初写入文件时保存的数据的顺序一致;
3.4.4 随机存取文件流
- RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口,既可作为输入流,也可作为输出流;
- RandomAccessFile支持随机访问方式,程序可以直接跳到文件的任意地方读、写文件(由于其对象包含一个记录指针用以标示当前读写处的位置),支持只访问文件的部分内容,或者向已存在的文件后追加内容;
- 如果RandomAccessFile作为输出流时,写出到的文件如果不存在则会在执行过程中自动创建,如果已经存在则会对原有文件内容从头覆盖;
RandomAccessFile实现数据的读写操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
RandomAccessFile raf1 = new RandomAccessFile(new File(String pathname, mode)) RandomAccessFile raf2 = new RandomAccessFile(new File(String pathname, mode))
byte[ ] buffer = new byte[int]; int len; while ((len = raf1.read(buffer)) != -1) { raf2.write(buffer, 0, len); }
raf1.close(); raf2.close();
|
RandomAccessFile实现数据的插入操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 方法:void seek(long pos):将文件记录指针定位到角标为pos位置
如何实现插入新的数据而不会覆盖后面数据的效果?
raf.seek(pos);
StringBuilder builder = new StringBuilder((int) new File().length);
byte[ ] buffer = new byte[int]; int len; while((len = raf.read(buffer)) != -1) { builder.append(new String(buffer, 0, len)); }
raf.seek(pos); raf.write("String".getBytes())
raf.write(builder.toString().getBytes())
|