File类
- File类的一个对象,代表一个文件或一个文件目录(文件夹)
- File类声明在java.io下
- File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间等方法,没有涉及到写入或读取文件内容的操作
- 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”
- 创建File类的实例(3种构造器)
File(String filePath)
File(String parentPath,String childPath)
File(File parentFile,String childPath) - 相对路径:相对于某个路径下,指明的路径(在一个module下的java文件写的即相对于该module而言的路径)
绝对路径:包含盘符在内的文件或文件目录的路径 - 路径分隔符
windows/DOS: \\
UNIX/URL: /
File类的常用方法
如:file1.renameTo(file2)
如果想返回true,需要file1在硬盘中存在,file2再硬盘中不存在
流
流的分类
- 操作数据单位:字节流、字符流
- 数据的流向:输入流、输出流
- 流的角色:节点流、处理流
- 对于文本类文件(.txt .java .c .cpp),使用字符流处理
- 对于非文本类文件(.jpg .mp3 .mp4 .avi .doc .ppt …),使用字节流处理
流的体系结构
抽象基类 | 节点流(或字符流) | 缓冲流(处理流的一种) |
InputStream | FileInputStream | BufferedInputStream |
OutputStream | FileOutputStream | BufferedOutputStream |
Reader | FileReader | BufferedReader |
Writer | FileWriter | BufferedWriter |
【属于字节流还是字符流看最后一个单词。Streamà字节流;Reader/Writerà字符流】
节点流/字符流:直接作用在文件上
缓冲流:作用在节点流/字符流上,或在缓冲流上
【从外部进Java环境→Input/Reader,从Java环境到外部→Output/Writer】
File file = new File("hello.txt");
文件在当前module中:语句写在@Test下路径相对于当前module;写在main()下路径相对于当前工程
读取:
public void test1() throws IOException {
//1.实例化File类的对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileReader fr = new FileReader(file);
//3.数据的读入
int data = fr.read();
while (data!= -1){
System.out.println((char)data);
data = fr.read();
}
//4.流的关闭
fr.close();
}
- read():返回读入的一个字符。如果达到文件末尾,返回-1
- 为了保证流资源一定可以执行关闭操作,要使用try-catch-finally
- 读入的文件一定要存在,否则报异常
read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
while ((len = fr.read(cbuf))!=-1){
//方式一、
for (int i = 0; i < len; i++) {
System.out.print(cbuf[i]);
}
//方式二
String str = new String(cbuf,0,len);
System.out.print(str);
}
写入:
public void test3(){
FileWriter fw = null;
try {
File file = new File("hello.txt");
fw = new FileWriter(file,true);
fw.write("good good !");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出操作,对应的File可以不存在
1) 如果不存在,在写入过程中,会自动创建此文件
2) 如果已经存在:
i) 使用构造器FileWriter(file,false)/ FileWriter(file):对原文件覆盖
ii) 使用构造器FileWriter(file,true):不会覆盖,在原文件基础上添加
缓冲流(处理流之一)☆
提升流的读取、写入速度:内部提供了一个缓冲区
public void test2(){
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File srcFile = new File("picture.jpg");
File desFile = new File("picture2.jpg");
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(desFile);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[5];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
资源关闭:先关外层缓冲流、再关内层节点流
【关闭外层流的同时,内层流也会自动进行关闭。所以内层流的关闭,可以省略】
转换流(处理流之二)☆
- 属于字符流
InputStreamReader:将一个字节的输入流转换为字符的输入流
OutputStreamWriter:将一个字符的输出流转换为字节的输出流 - 作用:提供字节流和字符流之间的转换
- 解码:字节、字节数组à字符数组、字符串
编码:字符数组、字符串à字节、字节数组 - 字符集
InputStreamReader isr = new InputStreamReader(fis ,"UTF-8");
参数1指明输入的字节流,参数2指明字符集(可以省略,使用系统默认的字符集)。具体使用哪个字符集,取决于文件xxx.txt保存时使用的字符集
标准输入、输出流(处理流之三)
- System.in:标准输入流,默认从键盘输入
System.out:标准输出流,默认从控制台输出 - System类的setIn(InputStream is)/setOut(PrintStream ps)方式重新制定输入和输出的流
打印流(处理流之四)
PrintStream
PrintWriter
提供了一系列重载的print()和println()
PrintStream ps = null;
FileOutputStream fos = new FileOutputStream("hello.txt");
ps = new PrintStream(fos, true);
if (ps!=null){
System.setOut(ps);
}
for (int i = 0; i <= 255; i++) {
System.out.println((char)i);
}
通过setOut()可以将输入流直接写进文件中,不在控制台显示
数据流(处理流之五)
DataInputStream
DataOutputStream
【数据流写入的文件正常打开显示的会有问题,需要用数据流读取再显示】
作用:用于读取或写出基本数据类型的变量或字符串
写入数据:
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
dos.writeUTF("孙狗");
dos.flush();//刷新,将内存中的数据写入文件
dos.writeInt(123);
dos.flush();
dos.close();
读取数据:
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String name = dis.readUTF();
int score = dis.readInt();
System.out.println(name+""+score);
将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中
【读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致,否则出错】
对象流(处理流之六)☆
- ObjectInputStream
ObjectOutputStream - 作用:存储和读取基本数据类型数据或对象的处理流。强大之处在于可以把Java中的对象写入到数据源中,也能把对象从数据源中还原。
- 序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去à ObjectOutputStream
反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象à ObjectInputStream - 可序列化的要求:
- 需要实现接口:Serializable
- 需要当前类提供一个全局常量(值可以自定义,不要重复)
public static final long serialVersionUID = 64645131234545L;
【如果没有显式定义serialVersionUID,java运行环境根据类的内部细节自动生成一个值。如果类的内部实例变量做了修改,serialVersionUID可能会发生变化。发生变化后反序列化可能会出错】
-
- 除了当前类需要实现Serializable接口外,必须保证其内部所有属性都是也必须是可序列化的。(默认情况下,基本数据类型可以序列化)
- ObjectInputStream和ObjectOutputStream不能序列化static和transient修饰的成员变量
随机存取文件流(处理流之七)
RandomAccessFile类
- 直接继承于java.lang.Object类,实现了DataInput和DataOutput
- 既可以作为一个输入流,又可以作为一个输出流
RandomAccessFile raf1 = new RandomAccessFile(File file, String mode);
mode:”r” 只读;”rw” 可读可写;【没有”w”】
3. 如果作为一个输出流时,写出到的文件如果不存在,则在执行过程中自动创建;
如果写出到的文件存在,会对原文件从头开始覆盖
4. seek(long pos):从下标为pos的位置开始覆盖