后端

File类的使用+IO流

菠萝猫 · 5月6日 · 2020年 154次已读

1.File类的使用

package com.test.IO.File;
import org.junit.Test;
import java.io.File;

/**

 * @Description:File类的使用

 * 1.File类的一一个对象,代表-一个文件或一一个文件 目录(俗称:文件夹)

 * 2.File类声明在java. io包下

 * 3. File类中涉及 到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,

 * 并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。

 * 4.后续Filej类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点".
   **/
   public class FileTest {
   /*
      如何创建File类的实例
      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对象

      2.路径分隔符
           windows: \ \
           unix:/
    */
   @Test
   public void test(){
       //内存层面的对象
       //构造器1
       File file = new File("hello.txt");//相对于当前module 相对路径
       File file2 = new File("G:\\OneDrive\\OneDrive - sdtbu.edu.cn\\java知识准备\\java编程源码\\java高级进阶\\src\\com\\test\\IO\\he.txt");//绝对路径
       System.out.println(file);
       System.out.println(file2);

       //构造器二
       File file3 = new File("G:\\OneDrive\\OneDrive - sdtbu.edu.cn\\java知识准备\\java编程源码\\java高级进阶\\src\\com\\test\\IO","he");//文件目录
       System.out.println(file3);
       //构造器三
       File file4 = new File(file3,"he.txt");//文件目录
       System.out.println(file4);

   }
   /*
   获取操作:
   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数组

   public boolean renameTo(File dest): 把文件重命名为指定的文件路径
   比如: file1. renameTo(file2)为例:返回布尔值
   要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。
   */

   /*
   判断功能
    public boolean isDirectory(): 判断是否是文件目录
    public boolean isFile() :判断是否是文件
    public boolean exists() :判断是否存在
    public boolean canRead() :判断是否可读
    public boolean canWrite() :判断是否可写
    public boolean isHidden() :判断是否隐藏
     */

    /*
    创建硬盘中对应的文件或文件目录
    public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
    public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。
    public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。

    删除磁盘中的文件或文件目录
    public boolean delete(): 删除文件或者文件夹
    删除注意事项:
    Java中的删除不走回收站。

     */
   }

2.IO流简单介绍

 /**
 * @Description:Java IO流
 * 1.原理:对于我们站在程序的角度
 * 输入流 input:文件->内存
 * 输出流 output:内存->文件
 *
 * 2.流的分类
 *  按操作数据单位:字节流(byte 8bit 图片视频等非文本) 、字符流(char 16bit 文本)
 *  按数据的流向:输入流 、输出流
 *  按流的角色:节点流(直接作用于文件的流)、处理流(已有的流之上包了一层)
 *
 * 3.抽象基类 不能实例化,具体实现由其子类
 * (抽象基类)    字节流         字符流
 * 输入流      InputStream     Reader
 * 输出流      OutputStream    Writer
 *
 * 4.流的体系结构
 * 抽象基类            节点流(或文件流)         缓冲流(处理流的-种)
 * InputStream       FileInputStream      BufferedInputStream
 * OutputStream      FileOutputStream     BufferedOutputStream
 * Reader              FileReader            BufferedReader
 * Writer              Filewriter            BufferedWriter
 * 
 * 5.具体操作基本按四步走,例题上面有显示。
 **/

file

节点流的使用

2.1.1字符流之节点流案例:FileReader+Filewriter

例一

将FileReader.txt文件内容读入程序中,并输出到控制台

        @Test
    public void testFileReader(){//相较于当前Module
        FileReader reader = null;
        try {
            //1.实例化File类的对象,指明要操作的文件
            File file = new File("FileReader.txt");
            //2.提供具体的操作
            reader = new FileReader(file);
            //3.数据的读入过程 一个一个读取
            //read():返回读入的一个字符。如果达到文件末尾,返回-1
            //方式一:
//        int read = reader.read();
//        while (read!=-1){
//            System.out.print((char) read);
//            read = reader.read();
//        }
            //方式二:语法上的修改
            int read;
            while((read = reader.read())!= -1){
                System.out.print((char) read);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //垃圾回收机制只回收JVM堆内存里的对象空间。
            //对其他物理连接比如数据库连接、输入流输出流、Socket连接无能为力
            //4.流的关闭操作
            try {
                if (reader!=null){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

注意

    public static void main(String[] args) {
        File file = new File( "hello. txt");//在main函数中实例化File类的对象,指明要操作的文件是相较于当前工程
}

说明点:
1.reader.read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1。
2.异常的处理:为了保证流资源-定可以执行关闭操作。需要使用try-catch-finally处理,写的时候可以先抛出异常,最后按上述的1,2,3,4步骤将1,2,3全部添加进try-catch,finally中去关闭流。
3.读入的文件一定要存在,否则就会报FileNotFoundException。

例二

在例一下,对read()操作升级:使用read的重载方法,一次读取一个数组的字符

```
        @Test
    public void testFileReader1(){
        FileReader reader = null;
        try {
            //1. File类的实例化
            File file = new File("FileReader.txt");
            //2. FileReader流的实例化
            reader = new FileReader(file);
            //3.读入的操作(数据很多时 不能一个一个读)
            //read(char[] cbuf): 返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;
            while ((len = reader.read(cbuf))!=-1){
                //方法一:
                //这里一定要写len 若为cbuf.length会读取不正确
                //每次读取是覆盖前面 若缺少时 之前的内容无法覆盖也会显示
//                for (int i = 0; i < len; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //String错误的写法
//                String str =new String(cbuf);
//                System. out. print(str);
                //String正确的方法 从头开始取 每次取len个
                String str = new String(cbuf, 0, len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源的关闭
            try {
                if (reader!=null){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
```

例三

从内存中写出数据到硬盘的文件里。

说明:
1.输出操作,对应的File可以不存在的。如果不存在,在输出的过程中,会自动创建此文件。
2.File对应的硬盘中的文件如果存在: .
FileWriter writer = new FileWriter(file,false); //覆盖 默认
FileWriter writer = new FileWriter(file,true);//追加

    @Test
    public void testFileWriter()  {
        FileWriter writer = null;
        try {
            //1.提供File类的对象,指明写出到的文件
            File file = new File("FileWriter.txt");
            //2.提供FileWriter的对象,用于数据的写出
            writer = new FileWriter(file,true);
            //3.写出的操作
            writer.write("i have a dream!\n");
            writer.write("i need!\n");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.流资源的关闭
            try {
                if(writer!=null){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

综合

        /*
        字符流读写操作结合
        不能使用字符流来处理图片等字节数据
     */
    @Test
    public void test4(){
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("FileReader.txt");
            File destFile = new File("FileWriter.txt");
            //2.创建输入流和输出流的对象
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);
            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;
            while ((len = fr.read(cbuf))!=-1){
                fw.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭流资源
            try {
                if (fr!=null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fw!=null) {
                        fw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

2.1.2字节流之节点流案例:FileInputStream和FileOutpuStream

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

例一

使用字节流FileInputStream处理文本文件。(可能出现乱码)

和字节流一样按四步走去操作。

    @Test
    public void testFileInputStream() {
        FileInputStream inputStream = null;
        try {
            File srcFile = new File("FileReader.txt");
            inputStream = new FileInputStream(srcFile);
            byte[] buffer = new byte[5];
            int len;
            while ((len=inputStream.read(buffer))!=-1){
                String str = new String(buffer,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream!=null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

综合

实现对图片的复制操作。

    @Test
    public void testFileInputStream1() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File("a.jpg");
            File desFile = new File("a2.jpg");
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(desFile);
            //复制过程
            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 (fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

处理流的使用

2.2.1处理流之一:缓冲流的使用

1.缓冲流:

BufferedInputStream、BufferedOutputStream

BufferedReader、BufferedWriter

2.作用:

提供流的读取、写入的速度,内部提供了一个缓冲区

案例

实现非文本文件的复制

        @Test
    public void BufferedStreamTest(){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcFile = new File("a.jpg");
            File desFile = new File("a3.jpg");
            //2.造流
            //2.1造节点流
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(desFile);
            //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();*/
    }

2.2.2处理流之二:转换流的使用

1.转换流: 属于字符流
InputStreamReader 将一个字节的输入流转换为字符的输入流
OutputStreamWriter 将一个字符的输出流转换为字节的输出流
2.作用:提供字节流与字符流之间的转换

3.解码:字节、字节数组—>字符数组、字符串
编码:字符数组、字符串—>字节、字节数组

例一

使用InputStreamReader

    @Test
    public void test() throws IOException {
        FileInputStream fis = new FileInputStream("FileReader.txt");
        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);
        }
    }

综合

综合使用InputStreamReader和utputStreamWriter

    @Test
    public void test2() throws IOException {
        File file1 = new File("FileReader.txt");
        File file2 = new File("FileReader2.txt");

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

        InputStreamReader isr = new InputStreamReader(fis);
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        //读写过程
        char[] cbuf = new char[20];
        int len;
        while ((len = isr.read(cbuf)) != -1) {
            osw.write(cbuf, 0, len);
        }
        isr.close();
        osw.close();
    }

2.3其他流的使用

1.标准的输入、输出流

2.打印流

3.数据流

    public class OtherStreamTest5 {
    /*
    1.标准的输入、输出流.
    1.1
    System.in:标准的输入流,默认从键盘输入
    System.out:标准的输出流,默认从控制台输出
    1.2
    System类的setIn(InputStream is) / setOut (PrintStream ps)方式重新指定输入和输出的流

    1.3练习:
    从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
    直至当输入“e”或者exit”时,退出程序。
    方法一:使用Scanner实现,调用next()返回一个字符串
    方法二:使用System. in实现。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){
                System.out.println("请输入字符串");
                String data = br.readLine();
                if("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
                    System.out.println("程序结束");
                    break;
                }
                String upperCase = data.toUpperCase();
                System.out.println(upperCase);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /*
    2. 打印流: PrintStream 和PrintWriter
    2.1提供了-系列重载的print()和println()
    */
    /*
    3.数据流
    3.1 DataInputStream和DataOutputStream
    3.2作用:用于读取或写出基本数据类型的变量或字符串
    */

}

2.4对象流的使用

1.objectInputStream和objectOutputStream

2.作用:用于存储读取基本数据类型数据对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来
3.要想一个java对象是可序列化的,需要满足相应的要求。见Person. java

4.序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去,使用ObjectOutputstream实现。

5.反序列化:将磁盘文件中的对象还原为内存中的一java对象,使用ObjectInputStreand

Person类

Person需要满足如下的要求,方可序列化

  • 1.需要实现接口: Serializable
  • 2.当前类提供一个全局常量:seriaLVersionUID
  • 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)
  • ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
  import java.io.Serializable;
  public class Person implements Serializable {
    public static final long serialVersionUID = 475463534532L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

对象流测试

    public class ObjectInputOutputStreamTest {
    /*
    序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    使用ObjectOutputstream实现
    */
    @Test
    public void testObjectOutputStream(){
        ObjectOutputStream oss = null;
        try {
            //1.造文件 造流
            oss = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //2.写出
            oss.writeObject(new String("我爱读书"));
            oss.flush();//刷新操作

            oss.writeObject(new Person("刘志",123));
            oss.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                oss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
    反序列化:将磁盘文件中的对象还原为内存中的一java对象
    使用ObjectInputStreand
    */
    @Test
    public void testObjectInputStream(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));
            Object obj = ois.readObject();
            String str = (String)obj;

            Person p = (Person)ois.readObject();

            System.out.println(str);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}


版权声明:本站采用 “知识共享署名 – 非商业性使用 – 相同方式共享 4.0 中国大陆许可协议” 进行许可,您可以转载本站文章,转载时请以超链接形式标明文章原始出处,Thanks.


0 条回应