IO
Input: 输入
Output: 输出
1.文件
java.io.File 它是对应者实际的文件或是文件夹(目录)
new File(String 文件路径)
new File("d:/1.txt"); // 可以使用 / 作为分隔符
new File("D:\\MySQL"); // 可以使用 \\ 作为分隔符
或者可以使用 File.separator
获取不同操作系统的分隔符
1.1文件对象的API
常用方法:
.isFile() ; 返回一个布尔值代表是否是文件
.isDirectory(); 返回一个布尔值代表是否是目录
File 也可以用来代表不存在的目录或文件:
.mkdir() 来创建一个目录
.mkdirs() 可以用来创建多级目录
File file = new File("D:\\a\\b\\c");
file.mkdirs();
exists() 用来判断一个文件或目录是否存在
.listFiles() 得到一个目录下的所有子目录和文件
File file = new File("D:\\6.23实训班共享");
File[] files = file.listFiles();
for(File f: files) {
System.out.println(f);
可以使用FilenameFilter接口来过滤需要的文件或文件夹:
File[] files2 = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.startsWith("笔")) {
return true;
} else {
return false;
}
}
});
for(File f :files2) {
System.out.println(f);
}
删除文件(立刻):
new File("D:\\6.23实训班共享\\测试.txt").delete();
删除文件(当程序运行结束):
new File("D:\\6.23实训班共享\\测试.txt").deleteOnExit();
重命名和移动:
new File("D:\\6.23实训班共享\\测试.txt").renameTo(new File("c:\\测试2.txt"));
1.2相对路径
ile file = new File("D:\\6.23实训班共享\\代码\\Day16-IO\\1.txt");// 绝对路径
System.out.println(file.exists());
System.out.println(System.getProperty("user.dir")); // 当前目录
File file2 = new File("1.txt"); // 相对路径
System.out.println(file2.exists());
System.out.println(file2.getAbsoluteFile());
2.IO流
Input 输入流: 从文件读取内容,文件对我来说就是输入流
Output 输出流: 向文件写入内容,文件对我来说就是输出流
tips: 流是单向的
2.1字节流(以字节为单位操作数据)
InputStream 抽象类 -> FileInputStream 文件输入流
OutputStream 抽象类 -> FileOutputStream 文件输出流
InputStream:
FileInputStream:从文件读取字节
BufferedInputStream:加入缓冲功能,提高文件的读取效率
ByteArrayInputStream:把字节数组变成输入流
OutputStream:
FileOutputStream:向文件写入字节
BufferedOutputStream:加入缓冲功能, 提高文件的写入效率
ByteArrayOutputStream:把流的内容写入字节数组
PrintStream:实际上就是System.out
读取内容:
1.一次读取一个字节
// 1. 创建输入流对象
FileInputStream fis = new FileInputStream(new File("1.txt"));
// FileInputStream fis = new FileInputStream("1.txt")
// 2. 读取内容
/*int read = fis.read();// 一次读取一个字节, 返回int中只用了一个字节
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println(read);*/
while(true) {
int read = fis.read();
if(read == -1) {
break;
}
System.out.println(read);
}
2.一次读取多个字节
// 1. 创建输入流对象
FileInputStream fis = new FileInputStream(new File("1.txt"));
// 2. 一次读取多个字节
byte[] buf = new byte[2];
/*int len = fis.read(buf);// 将读到的内容填充到byte数组中,返回的是读到的字节总数, 返回-1还是表示读取完毕了
System.out.println(len);
System.out.println(Arrays.toString(buf));
len = fis.read(buf);
System.out.println(len);
System.out.println(Arrays.toString(buf));
len = fis.read(buf);
System.out.println(len);*/
while(true) {
int n = fis.read(buf);
if(n == -1) {
break;
}
System.out.println(Arrays.toString(buf));
}
3.输出流
// 1.创建了输出流
FileOutputStream fos = new FileOutputStream("2.txt");
// 2. 向输出流写入内容
fos.write(97);
fos.write(98);
fos.write(99);
// 3. 关闭输出流
fos.close();
4.文件的复制
FileInputStream fis = new FileInputStream("1.txt");
FileOutputStream fos = new FileOutputStream("3.txt");
while(true) {
byte[] buf = new byte[1024];
int len = fis.read(buf);
if(len == -1) {
break;
}
fos.write(buf, 0, len); // 实际读到len个字节,就写入len个字节
}
fis.close();
fos.close();
2.2字符流
以字符为单位处理流的内容
Reader 字符输入流: InputStreamReader 将字节流转为字符流
Writer 字符输出流: OutputStreamWriter 将字节流转为字符流
Reader:
InputStreamReader:转换字节流为字符流
BufferedReader:功能增强,以行为单位读取数据 (装饰器模式)
FileReader:是InputStreamReader子类,将字符编码固定为操作系统的默认编码,不能手工改动
Writer:
OutputStreamWriter:转换字节流为字符流
PrintWriter:以行为单位写入数据
write:当成字符写入
print:将参数转为字符串后写入
FileWriter:是OutputStreamWriter的子类,固定了字符编码
public static void main(String[] args) throws IOException {
// 1. 将字节流转换为字符流
FileInputStream fis = new FileInputStream("1.txt");
// 注意:实际文件编码要与读取时的文件编码一致
InputStreamReader reader = new InputStreamReader(fis, "utf-8");
// 2. 读取
/*while(true) {
int c = reader.read();
if(c == - 1) {
break;
}
System.out.println((char)c);
}*/
while(true) {
char[] buf = new char[1024];
int len = reader.read(buf);
if(len == -1) {
break;
}
System.out.println(Arrays.toString(buf));
}
// 3. 关闭, 只需要关闭外层的流, 内部会帮我们关掉内层的流
reader.close();
}
BufferedReade**r是在InputStreamReader的基础上以行为单位**处理字符流
与 InputStreamReader是平级关系, 父类都是Reader
FileInputStream fis = new FileInputStream("1.txt");
InputStreamReader reader = new InputStreamReader(fis, "utf-8");
BufferedReader reader2 = new BufferedReader(reader);
/*System.out.println(reader2.readLine()); // 以行为单位读取数据
System.out.println(reader2.readLine()); // 以行为单位读取数据
System.out.println(reader2.readLine()); // 以行为单位读取数据*/
while(true) {
String line = reader2.readLine();
if(line == null) {
break;
}
System.out.println(line);
}
reader2.close();
BufferedReader与InputStreamReader的关系体现的是装饰者模式
装饰者模式:
- 装饰者与被装饰者需要有一个共同的父类
- 装饰者和被装饰者之间体现的是组合的关系,而不是继承的关系(目的是为了更加灵活)
- 装饰者会对被装饰者做功能上的增强