File和IO流

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字符集

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值