1. File类
该类的一个对象代表一个文件或目录(文件夹)
1.1 创建File类实例
| 构造器 | 说明 |
|---|---|
| File(String pathname) | 1、使用相对路径创建时,对于IDEA是相对于当前工程下的 2、使用绝对路径时,Windows和DOS系统使用"\"来隔开,为了区别转义符,Java代码层面则使用"\\";UNIX和URL使用"/"来隔开;也可以用常量File.separator |
| File(String parent, String child) | 根据parent路径名字符串和child路径名字符串创建一个新File实例 |
| File(File parent, String child) | 根据parent抽象路径名和child路径名字符串创建一个新File实例 |
(注:File对象只是内存层面上的,与实际硬盘上是否存在无关)
1.2 需要注意的方法
| 方法 | 说明 |
|---|---|
| File[] listFiles() | 获取当前目录下所有的文件或目录,得到File数组 |
| String[] list() | 获取当前目录下所有的文件或目录,得到String数组 |
| boolean renameTo(File dest) | 1、重新命名此抽象路径名表示的文件 2、要想 file1.renameTo(file2) 返回true,则file1要在硬盘中存在,file2不存在 |
| boolean createNewFile() | 创建文件;若硬盘中已存在,则不创建返回false |
| boolean mkdir() | 创建目录;若上层目录不存在,则不会创建 |
| boolean mkdirs() | 创建目录;即使上层目录不存在,也会一并创建 |
2. IO流
四个抽象基类如下
| (抽象基类) | 字节流 | 字符流 |
|---|---|---|
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |
IO流体系如下
| 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 | |
|---|---|---|---|---|
| 抽象基类 | InputStream | OutputStream | Reader | Writer |
| 访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
| 访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
| 访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
| 访问字符串 | StringReader | StringWriter | ||
| 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
| 转换流 | InputStreamReader | OutputStreamWriter | ||
| 对象流 | ObjectInputStream | ObjectOutputStream | ||
| FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
| 打印流 | PrintStream | PrintWriter | ||
| 推回输入流 | PushbackInputStream | PushbackReader | ||
| 特殊流 | DataInputStream | DataOutputStream |
2.1 FileReader
用于处理文本文件(.txt,.java,.c,.cpp等)的输入流
// 使用read()方法
@Test
public void testFileReader() {
FileReader fr = null;
// 为了保证流可以关闭,需要使用try/catch来处理异常
try {
File file = new File("E:\\JavaTest\\hello.txt");
fr = new FileReader(file);
int data;
while (-1 != (data = fr.read())) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fr)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 使用read(char[] cbuf)方法
@Test
public void testFileReader2() {
File file = new File("E:\\JavaTest\\hello.txt");
char[] buff = new char[5];
FileReader fr = null;
try {
fr = new FileReader(file);
int len;
while (-1 != (len = fr.read(buff))) {
// 这里循环的上限不能是buff.length,因为每调用read()就会把内容填进char数组中,
// 使用buff.length可能会在最后一次输出上一次的内容
for (int i = 0; i < len; i++) {
System.out.print(buff[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fr)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2 FileWriter
用于处理文本文件的输出流
@Test
public void testFileWriter() {
FileWriter fw = null;
try {
File file = new File("E:\\JavaTest\\hello.txt");
// 第二个参数表示以追加形式写数据,默认是覆盖
fw = new FileWriter(file, true);
fw.write("How are you\n");
fw.write("I'm fine\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fw)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.3 复制文本文件
// 复制文本文件
@Test
public void testCopy() {
File scr = new File("E:\\JavaTest\\src.txt");
File dest = new File("E:\\JavaTest\\dest.txt");
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(scr);
fw = new FileWriter(dest);
char[] buff = new char[10];
int len;
while (-1 != (len = fr.read(buff))) {
// 每次写len个字符
fw.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fw)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (null != fr)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.4 FileInputStream/FileOutputStream
字节流,可处理任意文件,输出文本文件到控制台时可能会出现乱码
@Test
public void testFileInputOutputStream() {
File src = new File("E:\\JavaTest\\src.jpg");
File dest = new File("E:\\JavaTest\\dest.jpg");
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dest);
byte[] buff = new byte[1024];
int len;
while (-1 != (len = fis.read(buff))) {
fos.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.5 缓冲流
@Test
public void testBufferedInputOutputStream() {
File src = new File("E:\\JavaTest\\src.jpg");
File dest = new File("E:\\JavaTest\\dest.jpg");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] buff = new byte[1024];
int len;
while (-1 != (len = bis.read(buff))) {
bos.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.6 转换流
- InputStreamReader:字节输入流 --> 字符输入流,解码
- OutputStreamWriter:字符输出流 --> 字节输出流,编码
@Test
public void test() {
File src = new File("E:\\JavaTest\\src.txt");
File dest = new File("E:\\JavaTest\\dest.txt");
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
isr = new InputStreamReader(fis, "UTF-8");
osw = new OutputStreamWriter(fos, "UTF-8");
char[] buff = new char[1024];
int len;
while (-1 != (len = isr.read(buff))) {
osw.write(buff, 0 , len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != isr) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != osw) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.7 数据流
DataInputStream和DataOutputStream,用于读写基本数据类型变量和String字符串
@Test
public void testDataStream() throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\JavaTest\\test.dat"));
dos.writeUTF("学海无涯");
dos.flush();
dos.writeInt(123);
dos.flush();
dos.writeBoolean(false);
dos.flush();
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream("E:\\JavaTest\\test.dat"));
// 读的顺序要与写的顺序一致
System.out.println(dis.readUTF());
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
dis.close();
}
2.8 对象流
ObjectInputStream和ObjecOutputStream,用于读写基本数据类型变量和对象,使用方法与上文的数据流基本相似
-
序列化:保存基本类型数据或对象
自定义的对象要想实现序列化,对应类得满足以下条件
1、实现Serializable接口
2、为该类提供全局变量serialVersionUID,类型是static final long
3、该类的内部属性必须是可序列化的
4、不能序列化static或transient修饰的内部属性
-
反序列化:读取基本类型数据或对象
3. RandomAccessFile
3.1 相关说明
-
该类直接继承于Object类,实现了DataInput和DataOutput接口。可用于修改文本文件
-
既可以作为输入流,也可以作为输出流
作为输出流时,如果文件不存在,则会自动创建;如果存在,则会覆盖原文件,但不是全部覆盖,是从头覆盖,能覆盖多少算多少
3.2 例题
需求:以追加的形式修改文本文件内容,从"123456789"修改为"123abc456789"
@Test
public void test2() throws Exception {
// 原文件内容为"123456789"
RandomAccessFile raf = new RandomAccessFile(new File("E:\\JavaTest\\hello.txt"), "rw");
// 把指针移到下标为3的位置
raf.seek(3);
// 保存下标3后面的字符
StringBuilder sb = new StringBuilder((int) new File("E:\\JavaTest\\hello.txt").length());
byte[] buff = new byte[20];
int len;
while (-1 != (len = raf.read(buff))) {
sb.append(new String(buff, 0, len));
}
// 追加"abc"
raf.seek(3);
raf.write("abc".getBytes());
// 再添加原来的字符
raf.write(sb.toString().getBytes());
raf.close();
}