java重点!IO流与文件操作
输入input,输出output
本文使用junit单元测试,如果你对这个不太了解,建议先去学习一下
文章目录
1.File类
1.1File类是什么
- java.io.File类:文件和文件目录路径的抽象表示
1.2File类功能
-
新建文件和目录
-
删除文件和目录
-
重命名文件和目录
注意:File类不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入流,输出流
想要在java中表示一个真实存在的文件或目录(可以理解为路径),必须有一个File对象。相当于File只是用来指定文件的路径,所以一个File对象指定的路径不一定是真实存在的。
-
一个File对象可以作为参数,传递给流的构造器,来指明读取或者写入的路径
1.3如何创建File类的实例
//使用文件路径拼接
File(String filePath)
//使用文件路径拼接
File(String parentPath,String childPath)
//第一个参数为一个File对象,把childPath拼接到File对象所对应的路径后面
File(File parentFile,String childPath)
/*路径分割:
win:\\
linux:/
*/
1.4File类方法
public String getAbsolutePath() //获取绝对路径
public String getPath() //获取路径
public String getNAME() //获取文件名称
//获取上一层文件路径 如果当前文件不存在 ,则返回null //如果没使用绝对路径,也返回null
public String getParent()
//获取文件长度(字节数) 目录没有长度 如果文件不存在则返回0
public long length()
//获取文件最后一次修改时间 如果不存在 则返回0
public long lastModified()
/*
下面是三个比较重要的类方法,这些操作如果文件不存在,则会报错
*/
//获取指定目录下的所有文件名,或者文件目录名的名称数组 //
public String[] list() //返回String数组
public String[] listFiles() //返回File数组
//File类移动文件,并重命名
public boolean renameTo(File dest) //参数为File对象
/*
File类方法使用案例如下:
--------------------------------------------------------------------------
*/
package com.fyp.servlet2;
import org.junit.jupiter.api.Test;
import java.io.File;
//File类对象的新建
public class fileTest {
@Test
public void test() {
File f1 = new File("hello.txt");
File f2 = new File("C:\\Users", "fyp");
File f7 = new File("C:\\Users", "fyp\\h1.txt");
// System.out.println(f1.getAbsolutePath());
// System.out.println(f2.getAbsolutePath());
// System.out.println(f1);
System.out.println(f7);
File f3 = new File(f2,"nihao1.txt");
// System.out.println(f3);
/*
*
* 下面是File类方法的使用
* */
System.out.println(f1.getAbsoluteFile());
System.out.println(f1.getName());
System.out.println(f1.getPath());
System.out.println(f1.getParent());
System.out.println(f1.length());
System.out.println(f1.lastModified());
System.out.println("--------------------------------------------------------");
File[] list = f2.listFiles();
for (File s :list){
System.out.println(s);
}
boolean b = f1.renameTo(f7);
System.out.println(b);
}
}
1.5File类方法-2
public boolean isDirectory() //判断是否是文件目录
public boolean isFile() //判断是否是文件
public boolean exists() //判断file对象的路径是否存在
public boolean canRead() //判断是否可以读
public boolean canWrite() //判断是否可写
pubiic boolean isHidden() //判断是否是隐藏文件
//-------------------------------------------------------
public void test2(){
File file = new File("hello.txt");
boolean directory = file.isDirectory();
boolean directory1 = file.isFile();
boolean exists = file.exists();
if (exists){
System.out.println("文件路径存在 ");
}
else {
System.out.println("文件路径不存在");
}
}
1.6File类方法-3
//创建一个文件,若文件存在,则不创建,返回false
//如果存在则创建 返回值为true
public boolean createNewFile()
//创建文件目录 ,如果存在,就不创建了,如果上级目录不存在也不创建
public boolean mkdir()
//创建文件目录 , 如果上层文件目录不存在,一并创建
public boolean mkdirs()
//--------------------------------
public boolean delete() //删除路径所指向的文件或者是文件目录
注:java中的删除不走回收站,也不可以递归删除
2. 流的分类
2.1 按照数据单位分类
它们四个都是定义好的抽象基类
- 字节流(8bit)
- 输入流:InputStream 对应节点流:FileInputStream 节点流对应缓冲流:BufferedInputStream
- 输出流:OutputStream 对应节点流:FileOuputStream 节点流对应缓冲流:BufferedOutputStream
- 字符流(16bit)
- 输入流:Reader 对应节点流:FileReader 节点流对应缓冲流:BufferedReader
- 输出流:Writer 对应节点流:FileWriter 节点流对应缓冲流:BufferedWriter
2.2 按照角色不同分类
- 节点流
- 直接连接文件到内存
- 处理流
- 作用在节点流上 ,辅助节点流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VS1ie2KI-1606743276820)(…/…/…/AppData/Roaming/Typora/typora-user-images/image-20201031153050816.png)]
2.3 IO流体系
3.流的使用案例
3.1FileReader读入数据的基本操作
FileReader的read()方法:
- read():返回读入的一个字符,如果达到文件末尾哦的话,返回-1
- read(char[] cubf) 返回每次读入数组中的字符的个数,如果达到文件末尾,同样也是返回-1
//第一个方法
package com.fyp.servlet2;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Iotest01 {
//把hello.txt文件读入程序中
@Test
public void testFileReader(){
FileReader f2=null; //先声明f2 ,因为finally里需要调用
try {
//1.实例化File类的对象,指明要操作的文件
File file = new File("hello.txt");
System.out.println(file.getAbsolutePath());
//2.提供具体的流
//FileReader f2 = new FileReader(file);
f2 = new FileReader(file);
//3.数据的读入
//read():返回读入的一个字符,如果达到文件末尾哦的话,返回-1
//方式一:
// int data=f2.read();
// while (data != -1){
// System.out.print((char) data);
// data = f2.read();
// }
//方式二: 语法上的修改
//此处采用try-catch-finally处理异常,防止因为出现异常导致流不能被正常关闭而出现资源泄漏
int data;
while ((data =f2.read() ) !=-1){
System.out.print((char) data);
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (f2!=null)
f2.close(); //4.流的关闭操作
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//第二个方法
@Test
public void testFileReader1(){
FileReader f2=null;
try {
File file = new File("hello.txt");
f2 = new FileReader(file);
char[] cbuf = new char[5];
int len;
while ((len=f2.read(cbuf))!=-1){
String str = new String(cbuf,0,len);
System.out.print(str);
};
}catch (IOException e){
}finally {
}
}
3.2FileWriter基本操作
- 从内存中写出数据到硬盘里
- 对应发File类对象指定的文件可以不存在,并不会报异常
- 如果不存在,则会自动创建该文件
- 如果文件存在:
- 如果流使用的构造器为FileWriter(file,false)或者FileWriter(file)----两者都是表示对原有文件的覆盖
- 如果流的构造器是FileWirter(file,true)----则不会对原有文件覆盖,而是在原有文件的上面进行追加
案例:
package com.fyp.servlet2;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileWritertest {
@Test
public void filewritertest() throws IOException {
File file = new File("hello123.txt");
FileWriter f2 = new FileWriter(file,true); //true 表示对文件进行追加
f2.write("i have a dream! \n");
f2.write("i have a dream");
f2.close();
}
}
3.3利用FileWriter和FileReader实现文本文件的复制
案例:
@Test
public void copytest() throws IOException{
File file = new File("hello123.txt");
File file1 = new File("nihao.txt");
FileReader fr = new FileReader(file);
FileWriter fw = new FileWriter(file1);
char[] cbuf = new char[5];
int len;
while ((len=fr.read(cbuf))!=-1){
//每次写出len个字符
fw.write(cbuf,0,len);
}
fr.close();
fw.close();
}
FileWriter和FileReader 不可以用来处理图片等,需要使用字节流来处理
- 文本文件,一般使用字符流进行处理
- 图片,视频文件等非文本文件,一般使用字节流处理
3.4使用字节流FileInputStream和FileOutputStream进行对非文本文件复制
案例:
@Test
public void testFIleOUTstream() throws IOException {
File file = new File("ea5fc2a639549799665ed510cb15ef3.jpg");
File file1 = new File("bj.jpg");
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file1);
byte[] buffer = new byte[5];
int len;
while ((len=fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fis.close();
fos.close();
}
3.5处理流之一,缓冲流的使用
缓冲流的作用:可以提高流的读取,和写入的速度
能够提高读写速度的原因是什么?
-
我们去看源码可以看到,缓冲流在内部有一个缓存区
private static int DEFAULT_BUFFER_SIZE = 8192;
-
对于输出的处理流:相当于说,我们每次把读入的字节存在这个大小为8192的缓冲区里,每达到8192以后,缓冲流就会去写入一次,刷新缓冲区,这样就提高了效率
-
对于输出的处理流:我们也可以手动的让他刷新缓冲区,可以调用缓冲流的flush()方法,如果调用了这个方法,即使没有满足8192也会去写入,并刷新
开发当中,一般考虑使用缓冲流
缓冲流是作用在节点流之上的,如果要使用缓冲流就 必须先创建对应的节点流对象
案例:
package com.fyp.servlet2;
import org.junit.jupiter.api.Test;
import java.io.*;
//缓冲流的使用
public class BufferedTest {
@Test
public void Bufferedstreamtest() throws IOException {
File file = new File("bj.jpg");
File file3 = new File("bj3.jpg");
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file3);
//下面写缓冲流,因为缓冲流需要作用在节点流上
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//读取和写入的过程
byte[] buffer = new byte[10];
int len;
while ((len=bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
//资源关闭,先关闭外层的处理流,然后再关掉节点流
//关闭处理流的同时,节点流也会自动的进行关闭,此时可以不用再去写节点流的关闭
bis.close();
bos.close();
fis.close();
fos.close();
}
}
@Test
public void bufferdreaderwritertest() throws IOException{
File file = new File("hello123.txt");
File file3 = new File("bj3.txt");
FileWriter fw = new FileWriter(file3);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
char[] cbuf = new char[5];
int len;
while ((len=br.read(cbuf))!=-1){
bw.write(cbuf, 0, len);
}
bw.close();
br.close();
}
BufferedReader的readline()方法说明
readline():
- 按行读取字符串
- 读取出每一行的字符串默认不包含换行
- 读取结束返回null
BufferedWriter有一个newline的方法,可以实现换行
使用案例:
@Test
public void bufferdreaderwritertest() throws IOException{
File file = new File("hello123.txt");
File file3 = new File("bj3.txt");
FileWriter fw = new FileWriter(file3);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
String data;
while ((data=br.readLine())!=null){
bw.write(data);
bw.write("1");
bw.newLine();
}
bw.close();
br.close();
}
3.6 处理流之二,转换流
属于字符流,看后缀
- InputStreamReader 将一个字节的输入流转换为一个字符的输入流
- OutputStreamWriter 将一个字符的输出流转换为一个字节的输出流
作用:提供字节流和字符流之间的转换
从字节,字节数组------》转换为字符数组,字符串 此过程称为解码
从字符数组,字符串 -------》 字节,字节数组 此过程称为编码
字符集说明:
1.常见的编码表
- ASCLL : 美国标准信息交换码
- ISO8859-1 : 拉丁码表。欧洲码表
- GB2312 : 中国的中文编码表,最多两个字节编码所有字符
- GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多两个字节编码
- Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配唯一的字符码。
.close();
br.close();
}
## 3.6 处理流之二,转换流
属于字符流,看后缀
1. InputStreamReader 将一个字节的输入流转换为一个字符的输入流
2. OutputStreamWriter 将一个字符的输出流转换为一个字节的输出流
作用:提供字节流和字符流之间的转换
从字节,字节数组------》转换为字符数组,字符串 此过程称为解码
从字符数组,字符串 -------》 字节,字节数组 此过程称为编码
## 字符集说明:
1.常见的编码表
- ASCLL : 美国标准信息交换码
- ISO8859-1 : 拉丁码表。欧洲码表
- GB2312 : 中国的中文编码表,最多两个字节编码所有字符
- GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多两个字节编码
- Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配唯一的字符码。
- utf-8 : 变成的编码方式,可用1-4个字节来表示一个字符