1. java.io.File类的使用
1.1 概述
File类及本章下的各种流,都定义在java.io包下。
1.2构造器
public File(String pathname) :以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。 public File(String parent, String child) :以parent为父路径,child为子路径创建File对象。 public File(File parent, String child) :根据一个父File对象和子文件路径创建File对象
@Test
public void test(){
//路径设置为 / \\
File file = new File("E:/io/hello.txt");
System.out.println(file);
File file1 = new File("abc");
System.out.println(file1.getAbsolutePath());
}
@Test
public void test2(){
File file = new File("E:\\abc\\", "abc.txt");
File file1 = new File("abc", "ab");
File file2 = new File(file1, "chen.txt");
System.out.println(file2);
}
路径:
**绝对路径:**从盘符开始的路径,这是一个完整的路径。 **相对路径:**相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。 IDEA中,main中的文件的相对路径,是相对于"当前工程" IDEA中,单元测试方法中的文件的相对路径,是相对于"当前module"
1.3常用方法
1、获取文件和目录基本信息
public String getName() :获取名称 public String getPath() :获取路径 public String getAbsolutePath():获取绝对路径 public File getAbsoluteFile():获取绝对路径表示的文件 public String getParent():获取上层文件目录路径。若无,返回null public long length() :获取文件长度(即:字节数)。不能获取目录的长度。 public long lastModified() :获取最后一次的修改时间,毫秒值
//测试常用方法
@Test
public void test3(){
//相对路径
File file = new File("hello.txt");
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println(file.getParent());
System.out.println(file.length());
System.out.println(file.lastModified());
}
2、列出目录的下一级
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
@Test
public void test5(){
File file = new File("E:\\io");
String[] FileArr = file.list();
for(String s:FileArr){
System.out.println(s);
}
File[] files = file.listFiles();
for(File f:files){
System.out.println(f);
}
}
3、File类的重命名功能
public boolean renameTo(File dest):把文件重命名为指定的文件路径。
//要想重命名成功 满足 file文件必须存在 file1文件目录存在 且.txt文件不存在
@Test
public void test6(){
File file = new File("hello.txt");
File file1 = new File("E:\\io\\io1\\chen.txt");
boolean success = file.renameTo(file1);
System.out.println(success? "命名成功":"命名失败");
}
4、判断功能的方法
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。
public boolean canRead() :判断是否可读
public boolean canWrite() :判断是否可写
public boolean isHidden() :判断是否隐藏
@Test
public void test7(){
File file = new File("E:\\io\\io1\\chen.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isHidden());
}
5创建、删除功能
public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false。
public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。
public boolean delete() :删除文件或者文件夹
删除注意事项:① Java中的删除不走回收站。② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。
//文件创建和删除
@Test
public void test8() throws IOException {
File file = new File("E:/io/a.txt");
if(!file.exists()){
boolean newFile = file.createNewFile();
if(newFile){
System.out.println("创建成功");
}
}else {
System.out.println("文件存在");
System.out.println(file.delete()? "删除成功":"删除失败");
}
}
//目录创建
@Test
public void test9(){
//前提是io目录存在 io4和io5不存在
File file = new File("E:\\io\\io4");
System.out.println(file.mkdir());
File file1 = new File("E:\\io\\io5");
System.out.println(file1.mkdirs());
File file2 = new File("E:/io/io6/io7");
System.out.println(file2.mkdirs()? "创建成功":"创建失败");
}
6.练习
6.1创建一个文件和hello.txt在同一目录下
public class TestExce {
public static void main(String[] args) {
//创建一个文件和hello.txt在同一目录下
File file = new File("hello.txt");
System.out.println(file.getAbsoluteFile());
File file1 = new File(file.getAbsoluteFile().getParent(),"abc.txt");
System.out.println(file1.getAbsoluteFile());
}
}
6.2输出一个文件下的jpg文件
public class TestExce {
public static void main(String[] args) {
//输出一个文件下的jpg文件
File file = new File("E:\\pic");
// String[] list = file.list();
// for(String s:list){
// if(s.endsWith(".jpg")){
// System.out.println(s);
// }
// }
//方法二 FilenameFilter过滤
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {//name为文件或者子文件的名称
return name.endsWith(".jpg");
}
});
for(File f:files){
System.out.println(f);
}
}
}
6.3遍历文件目录下的文件名称,包括子目录
public class TestExce {
@Test
public void test(){
File file = new File("E:\\io");
printFileName(file);
}
public void printFileName(File file){
if (file.isFile()){
System.out.println(file.getName());
}else if(file.isDirectory()){
File[] files = file.listFiles();
for(File f:files){
printFileName(f);
}
}
}
}
6.4删除指定目录
public class TestExce {
@Test
public void test(){
File file = new File("E:\\io");
deleteName(file);
}
public void deleteName(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f:files){
deleteName(f);
}
}
file.delete();
}
}
2.IO流原理及流的分类
Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行,可以看做是一种数据的流动
2.1 流的API
Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
(抽象基类) 输入流 输出流
字节流 InputStream OutputStream
字符流 Reader Writer
2.2节点流之一:FileReader\FileWriter
2.2.1字符输入流:Reader
public int read(): 从输入流读取一个字符。 虽然读取了一个字符,但是会自动提升为int类型。返回该字符的Unicode编码值。如果已经到达流末尾了,则返回-1。 public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。每次最多读取cbuf.length个字符。返回实际读取的字符个数。如果已经到达流末尾,没有数据可读,则返回-1。注意:当完成流的操作时,必须调用close()方法,释放系统资源,否则会造成内存泄漏。
1.读取文件 输入至控制台
通过throws 不能保证 流正常关闭
package com.chen.springbootholiday.TestIO;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestReader {
public static void main(String[] args) throws IOException {
//通过throws 不能保证 流正常关闭
//1.创建文本
File file = new File("hello.txt");
//2.创建输入流的字符,用于读取数据
FileReader fileReader = new FileReader(file);
//3.读取数据,将数据显示在控制台上
//read 一次只能读取一个 且为int 类型
//System.out.println((char) fileReader.read());
//方式一
// int data=(char)fileReader.read();
// while (data!=-1){
// System.out.print((char)data);
// data=fileReader.read();
// }
//方式二
int data;
while ((data=fileReader.read())!=-1){
System.out.print((char) data);
}
//4.关闭流 防止泄露
fileReader.close();
}
}
2.通过try catch finally 进行对流的关闭
减少对磁盘的交互 通过字符数组
public class TestLiu {
@Test
public void test(){
FileReader fileReader = null;
try {
File file = new File("hello.txt");
fileReader = new FileReader(file);
int data;
while ((data=fileReader.read())!=-1){
System.out.print((char)data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileReader!=null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//对test进行优化 减少读取数据时和磁盘的交互
@Test
public void test1(){
FileReader fileReader = null;
try {
File file = new File("hello.txt");
fileReader = new FileReader(file);
//读取数据
//创建字符数组
char [] cBuffer=new char[3];
int len;
while ((len=fileReader.read(cBuffer))!=-1){
//这里不要通过cBuffer长度进行循环 会出现错误
// for(int i=0;i<cBuffer.length;i++){
// System.out.print(cBuffer[i]);
// }
for(int j=0;j<len;j++){
System.out.print(cBuffer[j]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileReader!=null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2.2字符输出流:Writer
FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。 FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。 FileWriter(File file,boolean append): 创建一个新的 FileWriter,指明是否在现有文件末尾追加内容。
1.将数据写入文本中
//将数据写入到文本中
@Test
public void test2() throws IOException {
FileWriter fw = null;
try {
//1.指定文件对象
File file = new File("info.txt");
//2.创建写数据
fw = new FileWriter(file);
//3.进行具体写的过程
fw.write("I love you\n");
fw.write("you love me\n");
fw.write("yyds");
System.out.println("输出成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭资源
if(fw!=null)
fw.close();
}
}
2.进行文件的复制
//从现有的数据中获取数据 读取hello.txt 文件 且将数据给到 指定名字为hello_copy.txt文件
@Test
public void test3(){
FileReader fr = null;
FileWriter fw = null;
try {
//1.创建File类的对象
File srcFile = new File("hello.txt");
File destFile = new File("hello_copy.txt");
//2.创建输入 输出流
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3.具体的读入和写出
//创建字符数组 减少磁盘交互
char[] cBuffer=new char[3];
int len;//用来记录每次 cBuffer读取的数量 用于后面遍历做为条件
while((len=fr.read(cBuffer))!=-1){
fw.write(cBuffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭资源
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2.3小结
FileReader/FileWriter执行步骤 1.创建读取或者写出的File类的对象 2.创建输入流或者输出流 3.进行具体的操作 读入 read(char[] cbuffer) 写出 wirte(String str)\write(char[] cbuffer, 0,len) 4.关闭资源 ① 因为出现流资源的调用,为了避免内存泄漏,需要使用try-catch-finally处理异常 ② 对于输入流来说,File类的对象必须在物理磁盘上存在,否则执行就会报FileNotFoundException。如果传入的是一个目录,则会报IOException异常。 对于输出流来说,File类的对象是可以不存在的。 > 如果File类的对象不存在,则可以在输出的过程中,自动创建File类的对象 > 如果File类的对象存在, > 如果调用FileWriter(File file)或FileWriter(File file,false),输出时会新建File文件覆盖已有的文件 > 如果调用FileWriter(File file,true)构造器,则在现有的文件末尾追加写出内容。
2.3字符流FileInputStream\FileOutputStream
1.复制图片
@Test
public void test() throws IOException {
//1.创建File的对象
File srcFile = new File("abc.jpg");
File destFile = new File("abc_copy.jpg");
//2.字节输入输出流的创建
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//3.具体的操作
byte [] Buffer=new byte[1024];
int len;
while((len=fis.read(Buffer))!=-1){
fos.write(Buffer,0,len);
}
System.out.println("复制成功");
//4.关闭资源
fos.close();
fis.close();
}
2.复制文本文件
//需求 复制文本文件hello.txt --->hello_1.txt
@Test
public void test1() throws IOException {
//1.创建File的对象
File srcFile = new File("hello.txt");
File destFile = new File("hello_1.txt");
//2.字节输入输出流的创建
FileInputStream fis = new FileInputStream(srcFile);
// FileOutputStream fos = new FileOutputStream(destFile);
//3.具体的操作
byte [] Buffer=new byte[1024];
int len;
while((len=fis.read(Buffer))!=-1){
// fos.write(Buffer,0,len);
String str=new String(Buffer,0,len);
System.out.println(str);
}
System.out.println("复制成功");
//4.关闭资源
// fos.close();
fis.close();
}
3.小结
FileInputStream\FileOutputStream执行步骤
1.创建读取或者写出的File类的对象
2.创建输入流或者输出流
3.进行具体的操作
读入 read(byte[] buffer)
写出 write(Byte[] buffer, 0,len)
4.关闭资源在2.2.3小结基础上
字符流 处理纯文本文件
字节流通常处理 非文本文件 涉及到文件复制 也可以使用字节流
3.缓冲流
3.1BufferedInputStream和BufferedOutputStream
1.作用:提升读写效率
2.构造器
public BufferedInputStream(InputStream in) :创建一个 新的字节型的缓冲输入流。
public BufferedOutputStream(OutputStream out): 创建一个新的字节型的缓冲输出流。
//需求 复制abc.jpg 命名为abc_copy1.jpg //通过BufferedInputStream BufferedOutputStream
这里用throws抛出异常为了更情况看代码 使用try-catch-finally进行异常处理和资源关闭
@Test
public void test() throws IOException {
//1.创建File的对象
File srcFile = new File("abc.jpg");
File destFile = new File("abc_copy1.jpg");
//2.字节输入输出流的创建
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//创建缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.具体的操作
byte [] Buffer=new byte[1024];
int len;
while((len=bis.read(Buffer))!=-1){
bos.write(Buffer,0,len);
}
System.out.println("复制成功");
//4.关闭资源
//关闭外层资源也会将内层资源进行关闭
bos.close();
bis.close();
}
3.测试提升效率
//测试缓冲流 提升复制效率
@Test
public void testVideo() throws IOException {
long start=System.currentTimeMillis();
String src="D:\\系统\\系统默认\\桌面\\01.mp4";
String dest="D:\\系统\\系统默认\\桌面\\03.mp4";
//音频下载地址 http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4
//使用FileStream 1024 时间为151
// testFileStream(src,dest);
//使用Buffer 1024 时间为31
testBuffer(src,dest);
long end=System.currentTimeMillis();
System.out.println("使用的时间为"+(end-start));
}
//定义方法 用于编写FileInputStream和FileOutputStream BufferedInputStream BufferedOutputStream
//先测试FileInputStream和FileOutputStream
public void testFileStream(String src, String dest) throws IOException {
//1.创建File的对象
File srcFile = new File(src);
File destFile = new File(dest);
//2.字节输入输出流的创建
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//3.具体的操作
byte [] Buffer=new byte[1024];
int len;
while((len=fis.read(Buffer))!=-1){
fos.write(Buffer,0,len);
}
System.out.println("复制成功");
//4.关闭资源
fos.close();
fis.close();
}
//编写BufferedInputStream BufferedOutputStream
public void testBuffer(String src,String dest) throws IOException {
//1.创建File的对象
File srcFile = new File(src);
File destFile = new File(dest);
//2.字节输入输出流的创建
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//创建缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.具体的操作
byte [] Buffer=new byte[1024];
int len;
while((len=bis.read(Buffer))!=-1){
bos.write(Buffer,0,len);
}
System.out.println("复制成功");
//4.关闭资源
//关闭外层资源也会将内层资源进行关闭
bos.close();
bis.close();
}
3.2BufferedReader和BufferedWriter
字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。 BufferedReader:public String readLine(): 读一行文字。 BufferedWriter:public void newLine(): 写一行行分隔符,由系统属性定义符号
1.读取文件
//通过BufferedReader读取文本文件
@Test
public void test() throws IOException {
File file = new File("test.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
char [] cBuffer=new char[1024];
int len;//用来记录每次读取的数量
while((len=br.read(cBuffer))!=-1){
//方法一
// for(int i=0;i<len;i++){
// System.out.print(cBuffer[i]);
// }
//方法二
String str=new String(cBuffer,0,len);
System.out.println(str);
}
br.close();
}
//只读一行
@Test
public void test1() throws IOException {
File file = new File("test.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String data;
while ((data=br.readLine())!=null){
System.out.println(data);
}
br.close();
}
2.通过BufferedReader 和BufferedWrite进行文件的复制
//开发中使用try-catch-finally进行异常处理
@Test
public void test3() throws IOException{
File srcFile = new File("test.txt");
File destFile = new File("test_copy.txt");
BufferedReader br = new BufferedReader(new FileReader(srcFile));
BufferedWriter bw = new BufferedWriter(new FileWriter(destFile));
String data;
while((data=br.readLine())!=null){
//将读入的数据进行 写入
bw.write(data);
//换行
bw.newLine();
}
bw.close();
br.close();
}
读写文件比较大时候 通过缓冲流提升效率 涉及到嵌套的多个流时,如果都显式关闭的话,需要先关闭外层的流,再关闭内层的流 其实在开发中,只需要关闭最外层的流即可,因为在关闭外层流时,内层的流也会被关闭。
4.转换流 InputStreamReader 与 OutputStreamWriter
作用 实现字节和字符之间的转换
1.InputStreamReader
将输入型的字节流转换成 输入型的字符流
InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。
1.1输出字符集为UTF-8
@Test
public void test() throws IOException {
//1.创建file类对象
File file = new File("desc_UFT-8.txt");
//2.创建流对象
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"utf-8");//此时IDEA默认utf-8
//进行操作
char [] cBuffer=new char[1024];
int len;
while ((len=isr.read(cBuffer))!=-1){
String str = new String(cBuffer, 0, len);
System.out.println(str);
}
isr.close();
}
2.OutputStreamWriter
将输出型的字符流转换成输出型的字节流
OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。 OutputStreamWriter(OutputStream in,String charsetName): 创建一个指定字符集的字符流。
2.1输出字符集为GBK格式
@Test
public void test1() throws IOException {
//1.创建file类对象
File file = new File("desc_UFT-8.txt");
//2.创建流对象
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"GBK");//此时IDEA默认utf-8
//进行操作
char [] cBuffer=new char[1024];
int len;
while ((len=isr.read(cBuffer))!=-1){
String str = new String(cBuffer, 0, len);
System.out.println(str);
}
isr.close();
}
2.2复制文件 将GBK格式 转换成 utf-8
@Test
public void test2() throws IOException{
File file = new File("dest_gbk.txt");
File file1 = new File("dest_gbk_utf8.txt");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "GBK");
FileOutputStream fos = new FileOutputStream(file1);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
char [] cBuffer =new char[1024];
int len;
while ((len=isr.read(cBuffer))!=-1){
osw.write(cBuffer,0,len);
}
System.out.println("操作成功");
osw.close();
isr.close();
}
3.字符编码和字符集
3.1编码与解码
编码:字符(人能看懂的)--字节(人看不懂的)
解码:字节(人看不懂的)-->字符(人能看懂的)
3.2字符集