File类
File类构造方法
- public File(String pathname)
- public File(String parent, String child)
- public File(File parent, String child)
File类常用方法之get
- public String getAbsolutePath():获取绝对路径
- public String getPath() :获取路径
- public String getName() :获取名称
- public String getParent():获取上层文件目录路径。若无,返回null
- public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
- public long lastModified() :获取最后一次的修改时间,毫秒值
- public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
- public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
File常用方法之重命名
- public boolean renameTo(File dest):把文件重命名为指定的文件路径
File常用方法之判断
- public boolean isDirectory():判断是否是文件目录
- public boolean isFile() :判断是否是文件
- public boolean exists() :判断是否存在
- public boolean canRead() :判断是否可读
- public boolean canWrite() :判断是否可写
- public boolean isHidden() :判断是否隐藏
File常用方法之创建
- public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
- public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上层目录不存在,也不创建。 - public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建
File常用方法之删除
- public boolean delete():删除文件或者文件夹(要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录)
IO概述
流的分类
- 按照数据单位,分为:字节流(8bit)、字符流(16bit)
- 按照流向,分为:输入流、输出流
- 按照角色,分为:节点流、处理流
IO流的体系
文件流(节点流)
- FileReader, FileWriter 字符流用来读取和吸入文本文档,如.txt, .java, .html
- FileInputStream, FileOutputStream 字节流用来处理非文本文档,如.doc, .jpg, .mp3, .mp4
FileReader 文本字符输入流
- public int read():读取一个字符并返回,到了文件末尾时返回-1
- public int read(char cbuf[]):读取一定数量的字符至cbuf中,返回读取的长度,到了文件末尾时返回-1
@Test
public void testFileReader() {
// 1.创建文件
File file = new File("test.txt");
FileReader fileReader = null;
try {
// 2.创建输入流
fileReader = new FileReader(file);
// 3.读取输入
int c;
while ((c = fileReader.read()) != -1) {
System.out.print((char) c);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.关闭资源
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void testFileReader1() {
// 1.创建文件
File file = new File("test.txt");
FileReader fileReader = null;
try {
// 2.创建输入流
fileReader = new FileReader(file);
// 3.读取输入
char[] buffer = new char[5];
int len;
while ((len = fileReader.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.关闭资源
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileWriter 文本字符输出流
构造方法:
- public FileWriter(String fileName | File file, boolean append) : append为true时续写文件,append为false时重写文件
- public FileWriter(String fileName | File file), 相当于FileWriter(String fileName | File file, false)
注意事项:
- Writer和OutputStream操作的文件如果不存在,不会报错,并将自动创建该文件
@Test
public void testFileWriter() {
FileWriter fileWriter = null;
try {
// 1.创建文件
File file = new File("test1.txt");
// 2.创建输出流
fileWriter = new FileWriter(file, false);
// 3.写入
fileWriter.write("Hello World!\n");
fileWriter.write("我爱北京*\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.关闭资源
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileInputStream、FileOutputStream 文本字节输入输出流
/**
* 使用FileInputStream和FileOutputStream实现通用的文件拷贝
*/
public void fileCopy(String src, String dest) {
FileInputStream in = null;
FileOutputStream out = null;
try {
File srcFile = new File(src);
File destFile = new File(dest);
in = new FileInputStream(srcFile);
out = new FileOutputStream(destFile, false);
byte[] buffer = new byte[1024];
int len;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲流
原理
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节或字符的缓冲区
BufferedInputStream、BufferedOutputStream
public void fileCopy(String src, String dest) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
in.close();
}
BufferReader、BufferedWriter
注意点:
- BufferedReader除了可以使用read()方法之外,还封装了一个readLine()方法用于读取一行,到文件末尾时返回null
- readLine()方法返回的字符串不好含换行符,如需输出换行符,可手动拼接换行符或使用BufferedWriter.newLine()换行
public void testBufferedReaderWriter() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("test(1).txt"));
// 方式1:
// char[] cbuf = new char[10];
// int len;
// while ((len = reader.read(cbuf)) != -1) {
// writer.write(cbuf, 0, len);
// }
// 方式2:
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
writer.close();
reader.close();
}
转换流
转换流提供了字节流和字符流之间的转换,常用来时间文件编码的转换:
- InputStreamReader:将InputStream转换为Reader
- OutputStreamWriter:将Writer转换为OutputStream
public void utf8ToGbk() throws IOException {
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"), "UTF-8");
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("test_gbk.txt"), "GBK");
char[] cbuf = new char[10];
int len;
while ((len = reader.read(cbuf)) != -1) {
writer.write(cbuf, 0, len);
}
reader.close();
writer.close();
}
标准输入输出流(了解)
- System.in 标准输入流,类型是InputStream,默认输入设备是键盘,可通过System.setIn(InputStream in)设置输入设备
- System.out 标准输出流,类型是PrintStream,默认输出设备是控制台,可通过System.setOut(PrintStream out)设置输出设备
/**
* 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。
* 然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。
*/
public static void main(String[] args) throws IOException {
// 为了借助BufferedReader的readLine()方法,这里先把System.in(InputStream)转为转换流,又转为了缓冲流
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = reader.readLine()) != null) {
if (!line.equals("e") && !line.equals("exit")) {
System.out.println(line);
} else {
break;
}
}
reader.close();
}
打印流(了解)
打印流:PrintStream和PrintWriter
- 提供了一系列重载的print()和println()方法,用于多种数据类型的输出
- PrintStream和PrintWriter的输出不会抛出IOException异常
- PrintStream和PrintWriter有自动flush功能
- PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。
在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。 - System.out返回的是PrintStream的实例
public void testPrintStream() throws FileNotFoundException {
PrintStream out = new PrintStream(new FileOutputStream("test11.txt"));
System.setOut(out);
for (int i = 0; i <= 255; i++) {
System.out.print((char) i);
if (i % 50 == 0) {
System.out.println();
}
}
out.close();
}
数据流(了解)
数据流有两个类:(用于读取和写出基本数据类型、String类的数据)DataInputStream 和 DataOutputStream
/**
* 数据流:写入
*/
@Test
public void testDataOutputStream() throws IOException {
DataOutputStream out = new DataOutputStream(new FileOutputStream("test.dat"));
out.writeUTF("张三");
out.writeInt(30);
out.writeBoolean(true);
out.close();
}
/**
* 数据流:读取
*/
@Test
public void testDataInputStream() throws IOException {
DataInputStream in = new DataInputStream(new FileInputStream("test.dat"));
String name = in.readUTF();
int age = in.readInt();
boolean isAlive = in.readBoolean();
System.out.println("name:" + name);
System.out.println("age:" + age);
System.out.println("isAlive:" + isAlive);
in.close();
}
对象流
可序列化对象的要求:
- 需要实现接口:Serializable
- 当前类提供一个全局常量:serialVersionUID
- 类内部所有属性也必须是可序列化的(默认情况下,基本数据类型可序列化)
/**
* 对象序列化与反序列化
*/
public class IOTest7 {
/**
* 对象序列化
*/
@Test
public void testObjectOutputStream() throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("test.obj"));
out.writeObject("我爱你中国");
Person person = new Person("张三", 30, true);
out.writeObject(person);
out.close();
}
/**
* 对象反序列化
*/
@Test
public void testObjectInputStream() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("test.obj"));
String str = (String) in.readObject();
System.out.println(str);
Person person = (Person) in.readObject();
System.out.println(person);
in.close();
}
}
class Person implements Serializable {
public static final long serialVersionUID = 20211021L;
private String name;
private int age;
private boolean isAlive;
public Person(String name, int age, boolean isAlive) {
this.name = name;
this.age = age;
this.isAlive = isAlive;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", isAlive=" + isAlive +
'}';
}
}