File 初识IO流

File类概述

1.File类在包java.io.File下,代表操作系统的文件对象,文件包括文件和文件夹
2.File类提供了诸如:定位文件,获取文件本身的信息、删除文件、创建文件或文件夹等功能
3.不能读取文件内容
4.常用构建对象方式:File file = new File("路径")

/*
目标:学会创建File对象定位操作系统的文件(文件 文件夹)
 */
public class FileDemo {
    public static void main(String[] args) {
        //1.创建File对象(制定了文件的路径)
        //路径写法:D:/ORGIN/1234.jpg
        //          D:\ORGIN\1234.jpg
        // File.separator想要于一个斜杠
      File f = new File("D:\\ORGIN\\1234.jpg");
      long size = f.length();//文件的字节大小
        System.out.println(size);
        //2.File创建对象,支持绝对路径 也支持相对路径(重点)
        File f1 = new File("D:\\ORGIN\\1234.jpg");//绝对路径
        File f2 = new File("file-io-app/src/date.txt");//相对路径:一般定位模块中的文件.相对工程下
        System.out.println(f2.length());

        //3.File创建对象,可以是文件也可以是文件夹
        File f3 = new File("D:\\ORGIN\\");
        System.out.println(f3.exists());//判断文件夹存不存在
    }
}

绝对路径:盘符的路径,从盘符开始
相对路径:默认当前工程下的目录开始

File类的常用API

File类的判断文件类型、获取文件信息功能

public boolean isDirectory() 测试此抽象路径名表示的File是否为文件夹
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或文件夹的名称
public long lastModified() 返回文件最后修改的时间毫秒值

public class FileDemo02 {
    public static void main(String[] args) {
        //绝对路径创建一个文件对象
        File f1 = new File("D:\\ORGIN\\1234.jpg");
        //获取它的绝对路径
        System.out.println(f1.getAbsolutePath());
        //获取文件定义时候使用的路径
        System.out.println(f1.getPath());
        //获取文件的名称(带后缀)
        System.out.println(f1.getName());
        //获取文件的大小(字节大小)
        System.out.println(f1.length());
        //获取文件的最后修改时间()
        long time = f1.lastModified();
        System.out.println("最后修改时间"+ new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time));
    }
}

File类创建,删除文件的功能

pubilc boolean createNewFile() 创建一个新的空的文件
pubilc boolean mkdir() 只能创建一级文件夹
pubilc boolean mkdirs() 可以创建多级文件夹
pubilc boolean delete() 删除抽象路径上表示的文件或文件夹
注意删除只有文件夹为空才可以删除,文件直接被删除不走回收站,即使文件被系统占用也会被删除

File类的遍历功能

public String[] list() 获取当前目录下所有的“一级文件名称”到一个字符串数组中去返回
public File[] listFiles() 获取当前目录下所有的“一级文件对象”到一个文件对象数组中去返回

public class FileDemo04 {
    public static void main(String[] args) {
        //1.定位一个目录
        File f1 = new File("D:\\ORGIN");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }
        //2.一级文件对象
        //获取当前目录下所有的“一级文件对象”到一个文件对象数组中去返回(重点)
        File[] files = f1.listFiles();
        for (File f : files) {
            System.out.println(f.getAbsolutePath());
        }
    }
}

注意:
当调用者不存在时,返回null
当调用者是一个文件时,返回null
当调用者是一个空文件夹时,返回一个长度为0的数组
当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容

递归文件搜索

目标去D盘搜索D:\GamePP\GamePP.exe文件

public class RecusionDemo05 {
    public static void main(String[] args) {
        //2.传入目录和文件名称
      seachFile(new File("D:/"),"GamePP.exe");
    }/*
    1.搜索某个目录下的全部文件,找到我们想要的文件
    dir被搜索的源目录
    fileName 被搜索的文件名称
    */
    public static void seachFile(File dir,String fileName){
        //3.判断dir是否是目录
        if (dir !=null && dir.isDirectory()){
            //可以找了
            //4.提取当前目录下的一级文件对象
            File[] files = dir.listFiles(); //null []
            //5.判断是否存在一级文件对象,存在才可以遍历
            if (files != null && files.length > 0){
                for (File file : files) {
                    //6.判断当前遍历的一级文件对象是文件还是目录
                    if (file.isFile()){
                        //7.是不是咱们要找的,是的话输出路径即可
                        if (file.getName().contains(fileName)){
                            System.out.println("找到了:"+ file.getAbsolutePath());
                            //启动程序代码仅限.EXE
                            try {
                                Runtime r = Runtime.getRuntime();
                                r.exec(file.getAbsolutePath());
                            }catch (IOException e){
                                e.printStackTrace();
                            }
                        }
                    }else{
                        //8.是文件夹,需要继续递归寻找
                        seachFile(file,fileName);
                    }
                }
            }
        }else{
            System.out.println("对不起,当前搜索的位置不是文件夹,不支持");
        }
    }
}

IO流

字符集

计算机底层不可以直接存储字符的。计算机中底层只能存储二进制(0,1)
二进制是可以转换成十进制的
计算机底层可以表示十进制编号,计算机可以给人类字符进行编号储存,这套编号规则就是字符集。
常见的字符集:
ASCII:(数字,英文,符号)1个字节存储一个字符,一个字节是8位
GBK:大多数软件默认的中文编码表兼容ASCII,并支持繁体及部分日韩文字(一个中文以两个字节的形式储存)
Unicode:万国码容纳世界上大多数国家的所有常见文字和符号
注意:Unicode是万国码,以UTF-8编码后一个中文一般以三个字节的形式储存。
UTF-8也兼容ASCII编码表
技术人员都应该使用UTF-8的字符集编码
编码前和编码后的字符集需要一致,否则会出现中文乱码
在这里插入图片描述

字符集的编码、解码操作
String编码:
byte[] getBytes() 使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName) 使用指定的字符集将该String编码为一系列字节,将结果储存到新的字节数组中
String解码:
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte[] bytes,String charsetName) 通过指定的字符集解码指定的字节数组来构造新的String

public class Test {
    public static void main(String[] args) {
        String name ="abc啦啦啦";
        byte[] bytes = name.getBytes();
        System.out.println(bytes.length);
        System.out.println(Arrays.toString(bytes));

    }
}

IO流概述

I表示input,是数据从硬盘文件读入到内存的过程,称之输入,负责读
O表示output,是内存程序的数据从内存到写出到硬盘文件的过程,称之输出,负责写
IO流的分类:
字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流
字节输出流:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件/网络中的流称为字节输出流
字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流
字符输出流:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件/网络中的流称为字符输出流
文件字节输入流:FileInputStream
public FileInputStream(File file) 创建字节输入流管道与源文件对象接通
pubilc FileInputStream(String pathname) 创建字节输入流管道与源文件路径接通

pubilc int read() 每次读取一个字节返回,如果字节已经没有可以读取的返回-1
public int read(byte[] buffer) 每次读取一个字节数组返回,如果字节已经没有可以读取的返回-1

public class FileInputStreamDemo01 {
    public static void main(String[] args) throws Exception{
        //1.创建一个文件字节输入流管道与源文件接通
        //InputStream is = new FileInputStream(new File("file-io-app\\src\\date.txt"));
        //简化写法:
        InputStream is = new FileInputStream("file-io-app\\src\\date.txt");
        //2.读取一个字节
        //手动算法
        int b1 = is.read();
        System.out.println((char) b1);
        int b2 = is.read();
        System.out.println((char) b2);
        int b3 = is.read();
        System.out.println((char) b3);
        int b4 = is.read();//读取完毕返回-1
        System.out.println(b4);
        //循环算法
        int b;
        while((b = is.read())!=-1){
            System.out.println((char)b);
        }
    }
}

字节数组:

public class FileInputStreamDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个文件字节输入流管道与源文件接通
        InputStream is = new FileInputStream("file-io-app\\src\\date02");
        //2.定义一个字节数组,用于读取字节数组
        byte[] buffer = new byte[3];//   1 KB
        int len = is.read(buffer);
        System.out.println("读取了几个字节:"+ len);
        String rs = new String(buffer);
        System.out.println(rs);
        int len1 = is.read(buffer);
        System.out.println("读取了几个字节:"+ len1);
        String rs1 = new String(buffer,0,len1);//String构造器支持读取多少输出多少数据
        System.out.println(rs1);
        //buffer = [a b c]-[c d c]
        int len2 = is.read(buffer);
        System.out.println("读取了几个字节:"+ len2);
        String rs2 = new String(buffer);
        System.out.println(rs2);
        //3.改用循环,每次读取一个数组
        byte[] buffer = new byte[3];
        int len;   //记录每次读取的字节数
        while ((len = is.read(buffer)) != -1) {
            System.out.println(new java.lang.String(buffer,0,len));
        }
    }
}

一次性读完文件的全部字节:

public class FileInputStreamDemo03 {
    public static void main(String[] args) throws Exception {
        //1.创建一个文件字节输入流管道与源文件接通
        File f = new File("file-io-app\\src\\date03");
        FileInputStream is = new FileInputStream(f);
        //2.定义一个字节数组与文件的大小刚刚一样大
        byte[] buffer = new byte[(int)f.length()];
        int len = is.read(buffer);
        System.out.println("读取了多少个字节"+len);
        System.out.println("文件大小"+f.length());
        System.out.println(new String(buffer));
    }
}

文件字节输出流:FileOutputStream

public FileOutputStream(File file)	 创建字节输出流管道与源文件对象接通
public FileOutputStream(File file,boolean append)	 创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filepath)	 创建字节输出流管道与源文件路径接通
public FileOutputStream(String filepath,boolean append)	创建字节输出流管道与源文件路径接通,可追加数据
public class OutputStreamDemo04 {
        public static void main(String[] args) throws Exception {
            //1、创建一个文件字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream("file-io-app/src/out04.txt" , true); // 追加数据管道
            //OutputStream os = new FileOutputStream("file-io-app/src/out04.txt"); // 先清空之前的数据,写新数据进入
            // 2、写数据出去
            // a.public void write(int a):写一个字节出去
            os.write('a');
            os.write(98);
            os.write("\r\n".getBytes()); // 换行
            // os.write('徐'); // [ooo]
            //b.public void write(byte[] buffer):写一个字节数组出去。
            byte[] buffer = {'a' , 97, 98, 99};
            os.write(buffer);
            os.write("\r\n".getBytes()); // 换行
            byte[] buffer2 = "我是中国人".getBytes();
            // byte[] buffer2 = "我是中国人".getBytes("GBK");
            os.write(buffer2);
            os.write("\r\n".getBytes()); // 换行
            // c. public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。
            byte[] buffer3 = {'a',97, 98, 99};
            os.write(buffer3, 0 , 3);
            os.write("\r\n".getBytes()); // 换行
            // os.flush(); // 写数据必须,刷新数据 可以继续使用流
            os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用了
        }
    }

书写方法:
public void write(int a) 写一个字节出去
public void write(byte[] buffer) 写一个字节数组出去
public void write(byte[] buffer , int pos , int len) 写一个字节数组的一部分出去
实现数据追加:
public FileOutputStream​(String filepath,boolean append) 创建字节输出流管道与源文件路径接通,可追加数据
写出去的数据可以换行:
os.write(“\r\n”.getBytes()) \r\n
写出去的数据成功生效:
flush()刷新数据
close()方法是关闭流,关闭包含刷新,关闭后流就不能继续使用

使用字节流完成文件的复制:

public class CopyDemo05 {
    public static void main(String[] args) {
        try {
            // 1、创建一个字节输入流管道与原视频接通
            InputStream is = new FileInputStream("file-io-app/src/out04.txt");
            // 2、创建一个字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制OK");
            // 4、关闭流。
            os.close();
            is.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

字节流只要是前后文件格式,编码一致就可以进行一切文件的拷贝。本质是完全转移文件的底层字节

try-catch-finally

finally:在异常处理时提供finally块来执行所有清除操作,比如说IO流中的释放资源
特点:被finally控制的语句最终一定会执行,除非JVM退出
异常处理标准格式:try….catch…finally
finally代码块是最终一定要执行的,可以在代码执行完毕的最后用于释放资源。

public class TryCatchFinallyDemo1 {
    public static void main(String[] args) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // System.out.println(10/ 0);
            // 1、创建一个字节输入流管道与原视频接通
             is = new FileInputStream("file-io-app/src/out04.txt");
            // 2、创建一个字节输出流管道与目标文件接通
             os = new FileOutputStream("file-io-app/src/out05.txt");
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制OK");
         //   System.out.println( 10 / 0);
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            // 无论代码是正常结束,还是出现异常都要最后执行这里
            System.out.println("========finally=========");
            try {
                // 4、关闭流。
                if(os!=null)os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(test(10, 2));
    }
    public static int test(int a , int b){
        try {
            int c = a / b;
            return c;
        }catch (Exception e){
            e.printStackTrace();
            return -111111; // 计算出现bug.
        }finally {
            System.out.println("--finally--");
            // 哪怕上面有return语句执行,也必须先执行完这里才可以!
            // 开发中不建议在这里加return ,如果加了,返回的永远是这里的数据了,这样会出问题!
            return 100;
        }
    }
}

try-catch-resource

可以自动释放资源,让代码更加的简单

public class TryCatchResouceDemo2 {
    public static void main(String[] args) {
        try (
                // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // 1、创建一个字节输入流管道与原视频接通
               InputStream is = new FileInputStream("file-io-app/src/out04.txt");
                // 2、创建一个字节输出流管道与目标文件接通
               OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");
               // int age = 23; // 这里只能放资源
                MyConnection connection = new MyConnection(); // 最终会自动调用资源的close方法
                ) {
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制OK");

        } catch (Exception e){
            e.printStackTrace();
        }

    }
}

文件字符输入流

以内存为基准,把磁盘文件的数据以字符的形式读入到内存,读取文本文件内容到内存中去。

public FileReader(File file)               创建一个字符输入流与源文件对象接通
public FileReader(String filePath)    创建一个字符输入流与源文件路径接通
public int read()                                读取一个字符的编号返回! 读取完毕返回-1
public int read(char[] buffer)             读取一个字符数组,读取多少个字符就返回多少个数量,读取完毕返回-1
public class FileReaderDemo01 {
    public static void main(String[] args) throws Exception {
        // 目标:每次读取一个字符。
        // 1、创建一个字符输入流管道与源文件接通
        Reader fr = new FileReader("file-io-app\\src\\data06.txt");

        // 2、读取一个字符返回,没有可读的字符了返回-1
//        int code = fr.read();
//        System.out.print((char)code);
//
//        int code1 = fr.read();
//        System.out.print((char)code1);

        // 3、使用循环读取字符
        int code;
        while ((code = fr.read()) != -1){
            System.out.print((char) code);
        }
    }
}

按照字符数组循环进行读取数据,可以解决中文乱码的问题,性能也会更好

public class FileReaderDemo02 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字符输入流与源文件接通
        Reader fr = new FileReader("file-io-app/src/data07.txt");
        // 2、用循环,每次读取一个字符数组的数据。  1024 + 1024 + 8
        char[] buffer = new char[1024]; // 1K字符
        int len;
        while ((len = fr.read(buffer)) != -1) {
            String rs = new String(buffer, 0, len);
            System.out.print(rs);
        }

    }
}

文件字符输出流

public FileWriter(File file)	                                        创建字符输出流管道与源文件对象接通
public FileWriter(File file,boolean append)	            创建字符输出流管道与源文件对象接通,可追加数据
public FileWriter(String filepath)	                                创建字符输出流管道与源文件路径接通
public FileWriter(String filepath,boolean append)	创建字符输出流管道与源文件路径接通,可追加数据
public class FileWriterDemo03 {
    public static void main(String[] args) throws Exception {
       //1、创建一个字符输出流管道与目标文件接通
       //Writer fw = new FileWriter("file-io-app/src/out08.txt"); // 覆盖管道,每次启动都会清空文件之前的数据
        Writer fw = new FileWriter("file-io-app/src/out08.txt", true); // 覆盖管道,每次启动都会清空文件之前的数据
      //a.public void write(int c):写一个字符出去
        fw.write(98);
        fw.write('a');
        fw.write('徐'); // 不会出问题了
        fw.write("\r\n"); // 换行
      //b.public void write(String c)写一个字符串出去
        fw.write("abc我是中国人");
        fw.write("\r\n"); // 换行
      //c.public void write(char[] buffer):写一个字符数组出去
        char[] chars = "abc我是中国人".toCharArray();
        fw.write(chars);
        fw.write("\r\n"); // 换行
      //d.public void write(String c ,int pos ,int len):写字符串的一部分出去
        fw.write("abc我是中国人", 0, 5);
        fw.write("\r\n"); // 换行
      //e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        fw.write(chars, 3, 5);
        fw.write("\r\n"); // 换行
        // fw.flush();// 刷新后流可以继续使用
        fw.close(); // 关闭包含刷线,关闭后流不能使用
    }
}

字节流适合做一切文件数据的拷贝(音视频,文本)
字节流不适合读取中文内容输出
字符流适合做文本文件的操作(读,写)
读写字符文件数据建议使用字符流,复制文件建议使用字节流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值