【尚硅谷】Java学习笔记13之IO流(1)

1.File类的使用

1.1 File类的理解

  1. File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)
  2. File类声明在java.io包下
  3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
  4. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点"。

1.2 File的实例化

1.2.1 常用构造器

File(String filePath)
File(String parentPath,String childPath)
File(File parentFile,String childPath)

1.2.2 路径的分类

相对路径:相较于某个路径下,指明的路径。
绝对路径:包含盘符在内的文件或文件目录的路径

说明:
IDEA中:
如果大家开发使用JUnit中的单元测试方法测试,相对路径即为当前Module下。
如果大家使用main()测试,相对路径即为当前的Project下。

Eclipse中:
不管使用单元测试方法还是使用main()测试,相对路径都是当前的Project下。

1.2.3 路径分隔符

windows和DOS系统默认使用“\”来表示
UNIX和URL使用“/”来表示

1.3 File类的常用方法

1.3.1 File类的获取功能

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数组

1.3.2 File类的重命名方法

   public boolean renameTo(File dest)
   把文件重命名为指定的文件路径

比如:file1.renameTo(file2)为例:
要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。

public void test4(){
	File file1 = new File("hello.txt");
	File file2 = new File("D:\\io\\hi.txt");

	boolean renameTo = file2.renameTo(file1);
	System.out.println(renameTo)
}

1.3.3 File类的判断功能

public boolean isDirectory()
判断是否是文件目录

public boolean isFile() 
判断是否是文件

public boolean exists() 
判断是否存在

public boolean canRead() 
判断是否可读

public boolean canWrite() 
判断是否可写

public boolean isHidden() 
判断是否隐藏

1.3.4 File类的创建功能

创建硬盘中对应的文件或文件目录

public boolean createNewFile() 
创建文件。若文件存在,则不创建,返回false

public boolean mkdir() 
创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上层目录不存在,也不创建。

public boolean mkdirs() 
创建文件目录。如果此文件目录存在,就不创建了。
如果上层文件目录不存在,一并创建

1.3.5 File类的删除功能

删除磁盘中的文件或文件目录

public boolean delete()
删除文件或者文件夹

删除注意事项:1:Java中的删除不走回收站
			 2:要删除一个文件目录,
			 请注意该文件目录下不能包含文件或文件目录。

2 IO流概述

2.1 流的分类

  • 1.操作数据单位:字节流、字符流
  • 2.数据的流向:输入流、输出流
  • 3.流的角色:节点流、处理流

图示:在这里插入图片描述

2.2 流的体系结构

在这里插入图片描述
说明:红框对应的是IO流中的4个抽象基类。
蓝框的流需要大家重点关注。

2.3 重点的几个流结构

在这里插入图片描述

2.4 输入、输出的标准化过程

2.4.1 输入过程

① 创建File类的对象,指明读取的数据的来源。(要求此文件一定要存在
② 创建相应的输入流,将File类的对象作为参数,传入流的构造器中
③ 具体的读入过程:创建相应的byte[ ] 或 char[ ]。
④ 关闭流资源 说明:程序中出现的异常需要使用try-catch-finally处理。

2.4.2 输出过程

① 创建File类的对象,指明写出的数据的位置。(不要求此文件一定要存在
② 创建相应的输出流,将File类的对象作为参数,传入流的构造器中
③ 具体的写出过程:write(char[ ]/byte[ ] buffer,0,len)
④ 关闭流资源 说明:程序中出现的异常需要使用try-catch-finally处理。

3 节点流(或文件流)

3.1 FileReader/FileWriter的使用

3.1.1 FileReader的使用

	@Test
    public void testFileReader1()  {
        FileReader fr = null;
        try {
            //1.File类的实例化
            File file = new File("hello.txt");

            //2.FileReader流的实例化
            fr = new FileReader(file);

            //3.读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1){
                //方式一:
                //错误的写法
//                for(int i = 0;i < cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
                //正确的写法
                for(int i = 0;i < len;i++){
                     System.out.print(cbuf[i]);
                 }
                //方式二:
                //错误的写法,对应着方式一的错误的写法
//                String str = new String(cbuf);
//                System.out.print(str);
                //正确的写法
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fr != null){
                //4.资源的关闭
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
说明点:
1. read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
2. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
3. 读入的文件一定要存在,否则就会报FileNotFoundException。

3.1.2 FileWriter的使用

@Test
public void testFileWriter() {
    FileWriter fw = null;
    try {
        //1.提供File类的对象,指明写出到的文件
        File file = new File("hello1.txt");

        //2.提供FileWriter的对象,用于数据的写出
        fw = new FileWriter(file,false);//对原文件是否覆盖,true为不覆盖

        //3.写出的操作
        fw.write("I have a dream!\n");
        fw.write("you need to have a dream!");
    	} catch (IOException e) {
        e.printStackTrace();
    	} finally {
    	
        //4.流资源的关闭
        if(fw != null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
1. 输出操作,对应的File可以不存在的。并不会报异常
2. File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
   File对应的硬盘中的文件如果存在:
   		如果流使用的构造器是:
   		FileWriter(file,false) / FileWriter(file):对原文件的覆盖
   		如果流使用的构造器是:FileWriter(file,true):
   		不会对原文件覆盖,而是在原文件基础上追加内容

3.1.3 文本文件的复制:

	@Test
    public void testFileReaderFileWriter() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");

            //不能使用字符流来处理图片等字节数据
//            File srcFile = new File("爱情与友情.jpg");
//            File destFile = new File("爱情与友情1.jpg");


            //2.创建输入流和输出流的对象
             fr = new FileReader(srcFile);
             fw = new FileWriter(destFile);


            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到cbuf数组中的字符的个数
            while((len = fr.read(cbuf)) != -1){
                //每次写出len个字符
                fw.write(cbuf,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();
            }
        }
    }

3.2 FileInputStream / FileOutputStream的使用

* 1. 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
* 2. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt),使用字节流处理
/*
实现对图片的复制操作
 */
@Test
public void testFileInputOutputStream()  {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        //1.造文件
        File srcFile = new File("爱情与友情.jpg");
        File destFile = new File("爱情与友情2.jpg");

        //2.造流
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);

        //3.复制的过程
        byte[] buffer = new byte[5];
        int len;
        while((len = fis.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(fos != null){
        
            //4.关闭流
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fis != null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

}

【注意】
相对路径在IDEA和Eclipse中使用的区别?
IDEA:
如果使用单元测试方法,相对路径基于当前的Module的。
如果使用main()测试,相对路径基于当前Project的。

Eclipse:
单元测试方法还是main(),相对路径都是基于当前Project的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值