IO流

File类

  • File类的使用
    1. File类的一个对象,代表一个文件或一个文件目录(俗称文件夹)
    1. File类声明在java.io包下
    1. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,
  •  并未涉及修改,写入或读取文件内容。如需要读取或写入,必须要IO流
    
    1. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的终点
/*
    * 1. 如何创建File类的实例
    *   File(String filePath)
    *   File(String parentPath, String childPath)
    *   File(File parentFile,String childPath)
    *
    * 2. 相对路径和绝对路径
    *
    * 3. 路径分隔符: \\, /
    *
    * */
    @Test
    public void test1(){
        //构造器1:
        File file1=new File("hello.txt"); //相对于当前module
//        File file2=new File("D:\\workspace_idea1\\JavaSenior\\day08\\he.txt");

        System.out.println(file1);

        //构造器2:
//        File file3=new File("D:\\workspace_idea1","JavaSenior");

        
    }

File类常用方法

*如下的方法适用于文件目录
* public String[] list(): 获取指定目录下的所有文件或者文件目录的名称数组
* public File[] listFiles(): 获取指定目录下的所有文件或者文件目录的File数组
*
* public boolean renameTo(File dest): 把文件重命名为指定的文件路径
*   比如:file1.renameTo(file2)为例:
*       要想保住返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在
*
* public boolean isDirectory(): 判断是否是文件目录
* public boolean isFile(): 判断是否是文件
* public boolean exits(): 判断是否存在
* public boolean canRead(): 判断是否可读
* public boolean canWrite(): 判断是否可写
* public boolean isHidden(): 判断是否隐藏
*
* 创建文件目录
* public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
* public boolean mkdir(): 创建文件目录。如果此文件目录存在或者上层目录不存在,就不创建
* public boolean mkdirs(): 创建文件目录。如果上层文件目录不存在,一并创建
*
* 删除磁盘中的文件或文件目录
* public boolean delete(): 删除文件或文件夹
*   删除注意事项:
*   Java中的删除不走回收站

File测试题

/**
 * 判断指定目录下是否有后缀为.jpg的文件,如果有,就输出名称
 * @create 2021-01-10 下午3:44
 */
public class FindJPGFileTest {
   @Test
   public void test1(){
       File srcFile=new File("d\\code");
       String[] fileNames=srcFile.list();

       for (String name: fileNames){
           if (name.endsWith(".jpg")){
               System.out.println(name);
           }
       }
   }
}
/**
 * 遍历指定目录所有文件名称,包括子文件目录中的文件
 * 拓展1: 并计算指定目录占用空间的大小
 * 拓展2: 删除指定文件目录及其下的所有文件
 *
 * @create 2021-01-10 下午3:47
 */
public class ListFilesTest {
    public static void main(String[] args) {
        //递归: 文件目录
        /* 打印出指定目录所有文件名称,包括子文件目录中的文件*/

        //1. 创建目录对象
        File dir=new File("/Users/Documents/JavaProject");
        //2. 打印目录的子文件
        printSubFile(dir);

    }

    private static void printSubFile(File dir) {
        //打印目录的子文件
        File[] subfiles=dir.listFiles();

        for (File f:subfiles){
            if (f.isDirectory()){
                printSubFile(f);
            }else {
                System.out.println(f.getAbsolutePath());
            }
        }
    }

    //拓展1:求指定目录所在空间的大小
    public long getDirectorySize(File file){
        //file是文件,直接返回file.length()
        //file是目录,吧它下一级的所有文件大小相加
        long size=0;
        if (file.isFile()){
            size+=file.length();
        }else {
            File[] all=file.listFiles();
            for (File f:all){
                size+=getDirectorySize(f);
            }
        }
        return size;
    }

    //拓展2:删除指定目录
    public void deleteDirectory(File file){
        //如果file是文件,直接delete()
        //如果是目录,先把它下一级干掉,然后删除自己
        if (file.isDirectory()){
            File[] all=file.listFiles();
            // 循环删除的是file的下一级
            for (File f:all){
                deleteDirectory(f);
            }
        }
        //删除自己
        file.delete();
    }

}

IO 流

在这里插入图片描述

  • 一、流的分类:
    1. 操作数据单位:字节流,字符流
    1. 数据的流向:输入流,输出流
    1. 流的角色:节点流,处理流
  • 二、流的体系结构
  • 抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
  • InputStream FileInputStream BufferedInputStream
  • OutputStream FileOutputStream BufferedOutputStream
  • Reader FileReader BufferedReader
  • Writer FileWriter BufferedWriter

字节流

字符流

FileReader
/**
 * @create 2021-01-10 下午5:10
 */
public class FileReaderWriterTest {

    public static void main(String[] args) {
        File file =new File("hello.txt"); //相较于当前工程
        System.out.println(file.getAbsolutePath()); //cannot find

        File file1=new File("day09/hello.txt");
        System.out.println(file1.getAbsolutePath());
    }

    /*
    * 将day09下的hello.txt文件内容读入程序中,并输出到控制台
    *
    * 说明点:
    * 1. read()的理解:返回读入的一个字符,如果达到文件末尾,返回-1
    * 2. 异常的处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally
    * 3. 读入的文件一定要存在,否则会报FileNotFoundException
    * */
    @Test
    public void testFileReader() {
        FileReader fr= null;
        try {
            //1. 实例化File类对象,指明要操作的文件
            File file=new File("hello.txt"); //相较于当前Module
            //2. 提供具体的流
            fr = new FileReader(file);

            //3. 数据的读入
            //read(): 返回读入的一个字符,如果到达文件的末尾,返回-1
            int data=fr.read();
            while (data!=-1){
                System.out.print((char)data);
                data=fr.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 流的关闭
            try {
                if (fr!=null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    //对read()操作升级,使用read()重载方法
    @Test
    public void testFileReader1() throws IOException {
        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.println(cbuf[i]);
//                }
                //方式一
//                for (int i = 0; i < len; i++) {
//                    System.out.println(cbuf[i]);
//                }
                //方式二
                String str=new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr!=null){
                //4. 资源的关闭
                fr.close();
            }
        }
    }

FileWriter

/*
* 从内存中写出数据到硬盘的文件里
* 说明:
* 1. 输出操作,对应File可以不存在,
* 2. 如果不存在,在输出过程中,会自动创建
* 如果存在:
* 如果使用的构造器是:FileWriter(file,false): 对原有文件覆盖
* FileWriter(file,false): 内容后添加
* */

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

        //2. 提供FileWriter的对象,用于数据的写出
        FileWriter fw=new FileWriter(file);

        //3. 写出的操作
        fw.write("I have a dream! \n");
        fw.write("you need to have a dream!\n");

        //4. 流资源的关闭
        fw.close();
    }


// 文本文件复制
    @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");

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

            //3. 数据的读入和写出操作
            char[] cbuf=new char[5];
            int len;
            while ((len=fr.read(cbuf))!=-1){
                //每次写出len个字符
                fw.write(cbuf,0,len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 流资源的关闭
            if (fw!=null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fr!=null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

字节流

** 1、对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
2、对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt),使用字节流处理**

/**
 * 测试FileInputStream和FileOutputStream的使用
 *
 * 结论:
 * 1、对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
 * 2、对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt),使用字节流处理
 *
 */
public class FileInputOutputStreamTest {

    @Test
    public void testFileInputStream() {
        FileInputStream fis= null;
        try {
            //1. 造文件
            File file=new File("hello.txt");

            //2. 造流
            fis = new FileInputStream(file);

            //3. 读数据
            byte[] buffer=new byte[5];
            int len; //记录每次读取的字节的个数
            while ((len=fis.read(buffer))!=-1){
                String str=new String(buffer,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 关闭资源
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    /*
    实现对图片的复制
    * */
    @Test
    public void testFileInputOutputStream(){
        FileInputStream fis= null;
        FileOutputStream fos= null;
        try {
            //
            File srcFile=new File("01.jpg");
            File destFile=new File("02.jpg");

            //
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            //复制的过程
            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)
            {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis!=null)
            {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //指定路径下文件的复制
    public void copyFile(String srcPath,String destPath){
        FileInputStream fis= null;
        FileOutputStream fos= null;
        try {
            //
            File srcFile=new File(srcPath);
            File destFile=new File(destPath);

            //
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            //复制的过程
            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)
            {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis!=null)
            {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }   
}

练习

获取文本上每个字符出现的次数

public class WordCount {
    @Test
    public void testWordCount(){

        BufferedReader br= null;
        BufferedWriter bw= null;
        try {
            br = new BufferedReader(new FileReader("hello.txt"));
            bw = new BufferedWriter(new FileWriter("hello1.txt"));

            int c;
            HashMap<Character,Integer>count=new HashMap<>();
            while ((c=br.read())!=-1){
                char ch=(char)c;

                if (count.containsKey(ch)){
                    count.put(ch,count.get(ch)+1);
                }else {
                    count.put(ch,1);
                }
            }

            Set<Map.Entry<Character,Integer>> entrySet=count.entrySet();
            for (Map.Entry<Character,Integer>entry:entrySet){
                switch (entry.getKey()){
                    case ' ':
                        bw.write("whitespace="+entry.getValue());
                        break;
                    case '\t':
                        bw.write("tab="+entry.getValue());
                        break;
                    case '\r':
                        bw.write("enter="+entry.getValue());
                        break;
                    case '\n':
                        bw.write("line="+entry.getValue());
                        break;
                    default:
                        bw.write(entry.getKey()+"="+entry.getValue());

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

缓冲流

BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

  1. 作用:提供流的读取:写入的速度
  •  提高读写速度的原因:内部提供了一个缓冲区
    

使用BufferedInputStream和BufferedOutputStream

public class BufferedTest {

    /*
    实现非文本文件的复制
    * */
    @Test
    public void BufferedStreamTest(){
        BufferedInputStream bis= null;
        BufferedOutputStream bos= null;
        try {
            //1. 造文件
            File srcFile=new File("2101608177836_.pic_hd.jpg");
            File destFile=new File("2101608177836_2pic_hd.jpg");
            //2. 造流
            //2.1 造节点流
            FileInputStream fis=new FileInputStream(srcFile);
            FileOutputStream fos=new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3. 复制的细节:读取,写入
            byte[] buffer=new byte[10];
            int len;
            while ((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 资源关闭
            //要求:先关闭外层的流,再关闭内层的流
            if (bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //说明:关闭外层流的同时,内层流也会自动关闭,所以可省略
//        fos.close();
//        fis.close();
    }

    //实现文件复制的方法
    public void copyFileWithBuffered(String srcPath,String destPath){
        BufferedInputStream bis= null;
        BufferedOutputStream bos= null;
        try {
            //1. 造文件
            File srcFile=new File(srcPath);
            File destFile=new File(destPath);
            //2. 造流
            //2.1 造节点流
            FileInputStream fis=new FileInputStream(srcFile);
            FileOutputStream fos=new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3. 复制的细节:读取,写入
            byte[] buffer=new byte[10];
            int len;
            while ((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 资源关闭
            //要求:先关闭外层的流,再关闭内层的流
            if (bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

BufferedReader和BufferedWriter

 /*
    * 使用BufferedReader和BufferedWriter实现文本文件的复制
    * */
    @Test
    public void TestBufferedReaderBufferedWriter(){
        BufferedReader br= null;
        BufferedWriter bw= null;
        try {
            //
            br = new BufferedReader(new FileReader(new File("hello.txt")));
            bw = new BufferedWriter(new FileWriter(new File("hello1.txt")));

            //读写操作
            //方式一
//            char[] cbuf=new char[1024];
//            int len;
//            while ((len=br.read(cbuf))!=-1){
//                bw.write(cbuf,0,len);
//            }

            //方式二
            String data;
            while ((data=br.readLine())!=null){
                //方式一
//                bw.write(data+"\n"); //data不包含换行符
                //方式二
                bw.write(data);
                bw.newLine();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if (bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

转换流

    1. 转换流: 属于字符流
  •  InputStreamReader:将一个字节的输入流转换为字符的输入流
    
  • 解码:字节、字节数组–>字符数组,字符串
  •  OutputStreamWriter:将一个字节的输出流转化为字符的输出流
    
  • 编码:字符数组、字符串–>字节,字节数组
    1. 作用:提供字节流和字符流之间的转换
public class InputStreamReaderTest {
    //InputStreamReader的使用,实现了字节的输入流到字符的输入流的转换
    @Test
    public void test1() throws IOException {
        FileInputStream fis=new FileInputStream("hello.txt");

        //参数2指明了字符集
        InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); //使用系统默认字符集

        char[] cbuf=new char[20];
        int len;
        while ((len=isr.read(cbuf))!=-1){
            String str=new String(cbuf,0,len);
            System.out.println(str);
        }
        isr.close();
    }

    @Test
    public void test2() throws IOException {
        //1. 造文件,造流
        File file1=new File("hello.txt");
        File file2=new File("hello_gbk.txt");

        FileInputStream fis=new FileInputStream(file1);
        FileOutputStream fos=new FileOutputStream(file2);

        InputStreamReader isr=new InputStreamReader(fis,"utf-8");
        OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");

        //2. 读写过程
        char[] cbuf=new char[20];
        int len;
        while ((len=isr.read(cbuf))!=-1){
            osw.write(cbuf,0,len);
        }
        //3. 关闭资源
        isr.close();
        osw.close();
    }
}

其他流的使用

    1. 标准的输入、输出流
    1. 打印流
    1. 数据流
    1. 标准的输入、输出流
      1.1
      System.in
      System.out
      1.2
      System类的setIn(InputStream is)/ setOut(PrintStream ps)的方式
      1.3 练习:
      从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
      直至输入"e"或者"exit"时,退出程序
      方法一:Scanner --> next()返回一个字符串
      方法二:System.in --> BufferedReader的readLine()
    public static void main(String[] args) {
        BufferedReader br= null;
        try {
            InputStreamReader isr=new InputStreamReader(System.in);
            br = new BufferedReader(isr);

            while (true){
                String data=br.readLine();
                if ("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
                    System.out.println("Program end");
                }
                String upperCase=data.toUpperCase();
                System.out.println(upperCase);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
* 2. 打印流:PrintStream和PrintWriter
*
* 2.1 提供了一系列重载的print()和println()
* 2.2 练习:
 @Test
    public void test2(){
        PrintStream ps=null;
        try {
            FileOutputStream fos=new FileOutputStream(new File("D:\\IO\\text.txt"));
            // 创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新缓冲区)
            ps=new PrintStream(fos,true);
            if (ps!=null){
                System.setOut(ps);
            }
            for (int i = 0; i < 255; i++) { // 输出ASCII字符
                System.out.println((char) i);
                if (i%50==0){ // 每50个数据一行
                    System.out.println(); // 换行
                }
            }
        } catch (FileNotFoundException e){
            e.printStackTrace();
        } finally {
            if (ps != null){
                ps.close();
            }
        }
    }

/*
* 3. 数据流
* 3.1 DataInputStream和DataOutputStream
* 3.2 作用:用于读取或写出基本数据类型的变量或字符串
*
* 练习:将内存中的字符串,基本数据类型变量写出到文件中
* */

   @Test
    public void test3() throws IOException {

        DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));

        dos.writeUTF("xxx");
        dos.writeInt(13);
        dos.writeBoolean(true);
        dos.flush();

        dos.close();
    }

    @Test
    public void test4() throws IOException {
        //1.
        DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
        //2.
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println(name);
        System.out.println(age);
        System.out.println(isMale);

        //3.
        dis.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值