Java 文件IO流

Java 文件IO流,第1张

1、文件 *** 作--file
1.1 访问文件或文件夹(目录)的属性
getName();获取当前文件名字的方法
length();获取当前文件的长度
canWrite();判断文件是否可写
canRead();判断文件是否可读
isHidden();判断文件是否隐藏
isFile();判断当前路径是否是文件
isDriectory();判断当前路径是否是文件夹
getParent();获取当前路径的父级结构
getAbsolutePath();获取当前文件的完整路径

访问文件的路径 要看文件的名字 名字中带后缀 则加后缀 不带则不加

访问文件夹的路径 没有后缀,直接写文件路径即可

package day01;
​
import java.io.File;
import java.io.IOException;
​
/**
 * 1.可以访问文件或文件夹(目录)的属性
 * 

* 2.创建和删除文件或文件夹(目录) *

* 3.访问一个文件夹(目录)下的所有子项 */ public class FileDemo { public static void main(String[] args) throws IOException { //1.访问文件 //pathName --- 文件路径 //文件路径分类: // 绝对路径 : 指的是通过路径可以绝对的能访问到当前电脑的位置(开发基本不用 太局限.) // 相对路径 : ./ 指的是相对应用程序(项目) 的路径 ----(开发必用) //访问文件一般是要加后缀的. File file = new File("./demo.txt");//访问文件的方式 //1.获取当前文件路径的名字 String fileName = file.getName(); System.out.println(fileName); //2.获取当前文件的长度 (字节) long length = file.length(); System.out.println(length); //3.获取当前文件是否可写 System.out.println("是否可写:" + file.canWrite()); System.out.println("是否可读:" + file.canRead()); //4.获取当前文件是否隐藏 System.out.println("是否隐藏:"+ file.isHidden()); //5.可以当前file这个对象路径 是否是文件 System.out.println("是否是文件:"+file.isFile()); //6.可以获取当前文件存不存在的状态. System.out.println("文件是否存在"+file.exists()); //7.获取当前文件所在的父级路径 System.out.println("当前文件的父级路径:"+ file.getParent()); //8.获取当前文件的完整路径 System.out.println("当前文件的完整路径"+file.getAbsolutePath()); } } ​

 1.2 创建和删除文件或者文件夹(目录) 1.2.1 创建文件
package day01;
​
import java.io.File;
import java.io.IOException;
​
/**
 * 创建文件的使用演示类:
 */
public class CreateFileDemo {
    public static void main(String[] args) throws IOException {
        //在当前项目路径下创建一个文件
        File file = new File("./demo2.txt");//创建一个文件路径对象
        if(file.exists()){//判断当前文件路径的物理文件是否存在.
            System.out.println("文件已存在,不能进行创建");
        }else {
            //光标选中 错误提示  alt + Enter + Enter
            file.createNewFile();
            System.out.println("创建文件成功!!");
        }
​
    }

}
​
1.2.2 删除文件/文件夹
package day01;
​
import java.io.File;
import java.lang.reflect.Field;
​
/**
 * 删除除文件夹/文件的使用演示类:
 */
public class DeleteDirDemo {
    public static void main(String[] args) {
        //删除文件夹
        File dir = new File("./test/a/b/c/d/e");//一个文件夹路径的对象
        if(dir.exists()){//判断文件夹是否存在
            dir.delete();//只能删除空的文件夹
            //System.out.println("已删除");
        }else {
            //System.out.println("文件不存在");
        }
        //删除文件
        File file = new File("./demo2.txt");//一个文件路径的对象
        if(file.exists()){ //判断文件是否存在
            file.delete();//删除文件
            System.out.println("删除成功");
        }else {
            System.out.println("文件不存在!");
        }
    }
}
1.3 访问一个文件夹(目录)下的所有子项
package day01;
​
import java.io.File;
​
/**
 * 获取一个文件夹(目录)下的子项
 */
public class ListFilesDemo {
    public static void main(String[] args) {
        //获取当前项目路径下的所有子项
        File dir = new File(".");//一个文件夹路径对象
        if(dir.isDirectory()){//判断当前dir路径是否是文件夹
            File[] files = dir.listFiles();
            System.out.println(files.length);
            for (int i = 0; i < files.length; i++) {//遍历File数组 获取数组中每个文件
                System.out.println(files[i].getName());//打印每个文件的名字
            }
        }
​
    }
}
1.4 递归删除文件夹:

递归(recursion):是程序中常见的解决问题的方法(使用频率尽可能限制,因为效率低下)

递归使用时 ,容易产生死循环,使用递归的时候,一定要加if语句(做一个出口)

递归的思想:自己调自己(本方法内部调用本方法),也可以间接的调用自己

循环是重复执行某段代码,递归的重复是个过程

main{
    
    recursion();
    
}
​
public void recursion(){
    ...
    recursion();
    ...
}
package day01;
​
import java.io.File;
​
/**
 *  递归的使用演示类:
 *  删除文件夹的递归 *** 作。
 */
public class RecursionDemo {
    public static void main(String[] args) {
        deleteDir(new File("./test"));
        System.out.println("执行删除 *** 作。");
    }
    public static void deleteDir(File file){
        /*
        *  先判断 传入的file 文件路径对象 是否是 文件夹
        *    若是 获取下该文件夹有没有子项
        *    循环遍历 接收的子项File数组
        *    在循环里 再调用当前本方法 传递 当前数组每个对象
        *  如果不是文件夹  就直接 file.delete();
        * */
        if(file.isDirectory()){//判断当前文件路径是否是文件夹
            //若是  获取下该文件夹有没有子项
           File[] files = file.listFiles();//获取文件夹下所有子项
            for (int i = 0; i < files.length; i++) {
                deleteDir(files[i]);//递归:调用本方法传递子项路径
            }
        }
        file.delete();//执行删除
​
    }
​
​
}

获取文件夹(目录)下的所有子项,也可以有条件的进行获取

1.5 文件过滤器
package day01;
​
import java.io.File;
import java.io.FileFilter;
​
/**
 * 文件过滤器 可以有条件的进行筛选要获取的文件内容:
 */
public class ListFilesDemo2 {
    public static void main(String[] args) {
        //获取当前项目路径下的子项
        File file = new File(".");
        FileFilter filter = new FileFilter() {//创建文件过滤器的匿名内部类
            @Override
            public boolean accept(File filePath) { //重写实现 过滤的条件
                //contains 判断内容是否包含 o 这个字母
                return filePath.getName().contains("o");//过滤条件为true 则将文件存储(过滤)起来
            }
        };                          //方法参数 通过ctrl + P 查看
        File[] files = file.listFiles(filter);//传入文件过滤器对象
        System.out.println(files.length);
        for (int i = 0; i < files.length; i++) {
            System.out.println(files[i].getName());
        }
​
    }
​
}
1.6 Lambda表达式

JDK1.8以后,Java支持了lambda表达式

lambda表达式更好的关注逻辑如何去写,而不是语法,这样的写法是编译器认可的,但是.class文件会被还原

lambda表达式:使用匿名内部类实现接口,且接口只有一个抽象方法才能使用

package day01;

import java.io.File;
import java.io.FileFilter;

/**
 * lambda表达式的使用演示类:
 */
public class LambdaDemo {
    public static void main(String[] args) {
        //获取当前项目路径下的子项
        File file = new File(".");
//        FileFilter filter = new FileFilter() {
//            @Override
//            public boolean accept(File filePath) {
//                return filePath.getName().contains("o");
//            }
//        };
        //lambda 表达式的语法: 可以忽略 new FileFilter(接口名)  和 内部重写的方法名
        //1.可以忽略 new FileFilter(接口名)  和 内部重写的方法名
        FileFilter filter1 = (File filePath) ->{
            return filePath.getName().contains("o");
        };
        //2.当 内部方法的形式参数 只有一个的话  则参数类型可以省略  小括号可以省略
        FileFilter filter2 = filePath ->{
            return filePath.getName().contains("o");
        };
        //3.若内部重写的方法 方法体只有一行代码的话  {} 可以不写  return 也不要写
        FileFilter filter3 = filePath -> filePath.getName().contains("o");
//        File[] files1 = file.listFiles( filePath -> filePath.getName().contains("o"));
        File[] files = file.listFiles(filter3);
        for (int i = 0; i < files.length; i++) {
            System.out.println(files[i].getName());
        }
    }
}
2、IO流
2.1 io简介:

In/Out:相对于程序而言的输出(读取)输出(写出)的过程。

即:通过Java程序到磁盘读取数据的过程,我们成为In的过程,也就是读取(输入)

价格Java程序充的数据写入磁盘的过程,我们成为Out的顾鹏程,也就是写出(输出)

在Java中,根据处理的数据单位不通,分为字节流和字符流

字节流:一个字节(byte)一个字节的去读取,或者写出

字符流:一个字符一个字符的去读取或者写出

JDK核心类库中提供了IO相关的类,这些类都在包下

流的概念:

程序中俄数据读取和写入,可以想象成水流在管道中流动

--流只能单方向流动

--输入流用来读取in

--输入流用来写出out

--数据只能从头到尾顺序的读取一次或写出一次

节点流:可以从或向一个特定的地方(节点)读写数据

处理流:是对一个已存在的连接和封装,通过所封装的流的功能实现数据读写

处理流的特点:处理留的构造方法总是要带一个其他的流对象做参考,一个流对象经过其他流的多次包装,成为流的连接

通常节点流也被称之为低级流,处理流也被称之为高级流或者过滤流

节点流

OutputStream抽象类:此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节,并将这些字节发送到某个接收器

FileOutputStream字节输出流:直接插在文件上,直接写出文件数据

创建对象

FileOutputString(String name)

        创建一个向具有特定名称的文件中写入数据的输出文件流

FileOutputString(File name)

        创建一个向指定File对象 表示的文件中写入数据的文件输出流

FileOutputStream(File file,Boolean append)-追加

       创建一个向指定File对象表示的文件中写入数据的文件输出流

注意:以上构造方法中,如果参数指向的文件以及父目录都不存在,将会抛出FileNotFoundException异常!

如果参数指向的文件不存在,但文件所在的目录存在,将不会抛出异常,程序会自动创建该文件

 字节流和字符流:

字节流:针对二进制文件(文本,图片,音频,视频....)

InputStream(包含input都是输入流)

  -- FileInputStream

  -- BufferedInputStream

  -- ObjectInputStream

OutputStream(包含output的都是输出流)

  -- FileOutputStream

  -- BufferedOutputStream

  -- ObjectOutputStream

字符流:针对文本文件,读写容易发生乱码现象,在读写时最好指定编码集为utf-8

reader(reader结尾的都是字符输入流)

-- FileReader

  -- BufferedReader

  -- InputStreamReader

Writer(Writer结尾的都是字符输出流)

-- FileWriter

  -- BufferedWriter

  -- OutputStreamWriter

  -- PrintWriter/PrintStream

  IO流表格:

2.2 代码案例 2.2.1  FileOutputStream
//FileOutputStream代码案例
package Part02IO;
import java.io.*;
/**
 * 文件输出流的使用演示类:
 * FOS -->FileOutputStream
 */
public class FOSDemo {
    public static void main(String[] args) throws IOException {
        /**
         *  文件输出流:通过程序写出 到磁盘上某个路径。
         */                         // alt + enter + enter
        //第一种:
        FileOutputStream fos = new FileOutputStream("./fos.dat");
//        //第二种:
//        File file = new File("./fos.dat");
//        FileOutputStream fos1 = new FileOutputStream(file);
        /**
         *   void write(int d) 写入的方法
         *   将给定的int值对应二进制 写入到"低八位"  然后再写入到文件中
         *   int 占  4个字节   在计算机中表示 32 位  32个0来表示
         *                              vvvvvvvv
         *   00000000 00000000 00000000 00000001
         */
        //给 fos.dat 写入 00000001
        fos.write(1);//写入int的数据  --1
        /**
         * 将给定的int值对应二进制 写入到"低八位"  然后再写入到文件中
         *                            vvvvvvvv
         * 00000000 00000000 00000000 00000010
         * */
        //因为在上面已经为fos.dat写入 00000001  所以继续往后写入的话 会在后面追加
        // 00000001  00000010
        fos.write(2);
        fos.close();//释放 (关闭流体)
    }
}

InputStream 抽象类

此抽象没事表示字节输入流的的所有类的超类/抽象类

FileInputSteam 子类

直接插在文件上直接读取文件数据

创建对象

FileInputStream(File file)

        通过打开一个实际文件的连接来创建一个FileInputStream,该文件通过文件系统的File对象file指定

FileInputStream(String pathname)

        通过打开一个实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定

 2.2.2 FileInputStream
//FileInputStream代码案例
package Part02IO;
import java.io.FileInputStream;
import java.io.IOException;
/**
 * 文件输入流的使用演示类
 * FIS --->FileInputStream  用于读取文件
 */
public class FISDemo {
    public static void main(String[] args) throws IOException {
        //创建文件输入流 并指定 要处理的文件路径
        FileInputStream fis = new FileInputStream("./fos.dat");
        /**
         *  int read()  调用则读取一个字节 返回的则是文件对应的二进制数据
         *
         *  fos.dat  文件内容:
         *  00000001  00000010  文件末尾
         *                      ^^^^^^
         * */
        //  d :00000000 00000000 00000000 00000001
        int d = fis.read();
        System.out.println(d);
        //  d:00000000 00000000 00000000 00000010
        d  = fis.read();
        System.out.println(d);
        //  d:11111111  11111111 11111111 11111111
        d = fis.read(); //文件末尾 -1
        System.out.println(d);
        fis.close();//需要释放
    }
}
2.2.3 复制文件代码案例
package Part02IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
 * 文件的拷贝使用演示类:
 */
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        //1.输入流
        FileInputStream fis = new FileInputStream("./paimeng.jpg");//获取源图片
        //2.输出流
        FileOutputStream fos = new FileOutputStream("./paimeng_Copy.jpg");//目标图片位置
        /**
         *  假设  :paimeng.jpg 文件内容
         *  11110000   11110000   00100100 ......
         */
        //如果读到的数据 为 -1 读到文件末尾
        //不明确循环次数, 已知循环条件
        int d;      //alt + enter + enter
        while ((d = fis.read()) != -1) { //如果读到的内容不为 -1的话
            //获取当前读到的字节内容
            /**
             *  paimeng_Copy.jpg 文件内容:
             *  11110000 11110000 00100100 ....
             */
            fos.write(d);//写入到 目标文件中
        }
        System.out.println("拷贝完毕!");
        fis.close(); //释放
        fos.close();//释放
    }
}
2.2.4 块读写优化代码案例
package Part02IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 通过块读写的方式 提高文件 拷贝的速度:
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        //1.输入流
        FileInputStream fis = new FileInputStream("./1.pptx");//获取源图片
        //2.输出流
        FileOutputStream fos = new FileOutputStream("./1_copy.pptx");//目标图片位置
        int d;
        byte[] data = new byte[1024*10]; //10kb
        long start = System.currentTimeMillis();//获取当前系统时间 毫秒单位
        while ((d = fis.read(data)) != -1) { //块读
            fos.write(data);//块写入
        }
        long end = System.currentTimeMillis();
        System.out.println("拷贝完毕!拷贝时长:"+ (end - start)+"ms");
        fis.close();//释放
        fos.close();//释放
    }
}
2.2.5 写入字符串
package Part02IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class WriteStringDemo {
    public static void main(String[] args) throws IOException {
        //向一个文件名为demo1.txt写入文本数据
        //crtl+alt+v 快速生成变量名
        FileOutputStream fos = new FileOutputStream("demo1.txt");
        String line = "beep,beep,i'm sheep~beep,beep,i'm sheep~";
        /*
        * String提供了将字符串转换为一组字节的方法
        * 使用的字符集通常都是UTF-8
        * java.nio.charset.StandardCharsets下的UTF-8
        * */
        byte[] data = line.getBytes(StandardCharsets.UTF_8);
        fos.write(data);
        fos.write("哔,哔,安慕希~哔,哔,安慕希~".getBytes(
                StandardCharsets.UTF_8));
        System.out.println("写出完毕!!!");
        fos.close();
    }
}
2.2.6 简易笔记本
package Part02IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * 实现简易的记事本工具
 * 程序启动后,要求在控制台输入的每一行的字符串,都会写入到note.txt,
 * 当我们在控制台输入exit时,程序退出
 */
public class TestNotes {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请开始输入内容,单独输入exit退出~~");
        //绑定要写出的文件是note.txt
        FileOutputStream fos = new FileOutputStream("note.txt");
        while (true){//一直循环接收用户输入的内容
            //接收用户每次在控制台输入的字符串
            String line = scanner.nextLine();
            //如果输入的内容line是exit,退出程序(退出循环)
            //不建议这种写法,因为line作为对象,可能会是null,就会引发空指针
            //if (line.equals("exit")){}
            //equalsIgnoreCase() 忽略大小写比较字符串
            if ("exit".equals(line)){
                break;//跳出当前循环
            }
            //将输入的内容写出到note.txt文件中
            fos.write(line.getBytes(StandardCharsets.UTF_8));
        }
//        String line;
//        while (!"exit".equals(line =scanner.nextLine())){
//            fos.write(line.getBytes(StandardCharsets.UTF_8));
//        }
        fos.close();
    }
}
2.2.7 文件追加模式案例
package Part02IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

/**
 * 文件输出对象追加模式
 */
public class TestNotes2 {
    public static void main(String[] args) throws Exception {
        /*
        * 文件流中有两种创建方式:覆盖模式和追加模式
        * 构造器:
        *   new FileOutputStream(String path)
        *   new FileOutputStream(File file)
        * 以上两种都是覆盖模式的构造器,这种情况创建文件输出流时,如果连接的文件已经存在,
        * 则会把文件之前的内容清空
        * 构造器:
        *   new FileOutputStream(String path,boolean append)
        *   new FileOutputStream(File file,boolean append)
        * 如果第二个参数传入true,则文件流为追加模式,如果连接的文件已经存在,
        * 则会把文件之前的内容保存
        * */
        FileOutputStream fos = new FileOutputStream("fos.txt", true);
        String line = "你叉叉,穷哈哈~哈利波特骑着扫帚飞~~~sorry,sorry";
        fos.write(line.getBytes(StandardCharsets.UTF_8));
        System.out.println("写出完毕");
        fos.close();

    }
}
2.3 处理流 2.3.1 缓冲流

BufferedOutPutStream 缓冲输出流

BufferedInputStream 缓冲输入流

复制文件代码案例

package Part02IO;

import java.io.*;

/**
 * 使用缓冲流实现复制文件案例
 */
public class CopyDemo3 {
    public static void main(String[] args) throws Exception {
        //创建一个文件字节输入流(低级流)
        FileInputStream fis = new FileInputStream("1.pptx");
        //创建一个缓冲字节输入流(高级流) 加快读取效率
        BufferedInputStream bis = new BufferedInputStream(fis);
        //创建一个文件字节输出流(低级流)
        FileOutputStream fos = new FileOutputStream("1_copy2.pptx");
        //创建一个缓冲字节输出流(高级流) 加快写出效率
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int d;
        long start = System.currentTimeMillis();
        //此处需要使用高级流对象bis获取内容
        while ((d = bis.read())!=-1){
            //此处需要使用高级流对象bos写入内容
            bos.write(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+(end-start)+"ms");
        //释放流资源 关闭流的顺序随意,而且只需要关闭高级流即可,会自动关闭连接的流
        bis.close();
        bos.close();
    }
}
2.3.2 fush代码案例
package Part02IO;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 缓冲流写出数据的缓冲区问题
 */
public class BOSFlushDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("bos.txt");
        //缓冲流内部维护了一个8K的字节数组,写出的数据都会先存入到这个数组中,
        //只有数组存满时,才会写出
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("听我说谢谢你~因为有你,温暖了四季~~~".getBytes(StandardCharsets.UTF_8));
        System.out.println("写出完毕!");
        //flush 冲水 方法的作用是让缓冲输出流将其中的缓冲区中已经缓存的数据立即写出
        bos.flush();
        //bos.close();
    }
}
2.4 对象流
package Part02IO;

import java.io.Serializable;
import java.util.Arrays;

public class Person implements Serializable {
    /*
    * 当一个类实现了可序列化接口时,最好显示的定义下面的属性:serialVersionUID
    * 即:序列化版本号
    * 当对象输出流在进行对象序列化时,会查看是否有显示的序列化版本,如果没有,
    * 则会自动根据类中内容生成一个唯一的版本号(如果这个类的结构发生变化,就会重新
    * 生成一个新的版本号),所以如果反序列化时,会查看版本号,如果版本号一致,就可以反序列化,
    * 如果类的内容发生变化,版本号发生变化,则反序列化会判断不一致,导致反序列化失败
    * 为了防止这种问题的发生,我们会开启兼容模式,就是固定死版本号
    * */
    static final long serialVersionUID = 1L;
    private String name;//姓名
    private int age;//年龄
    private String gender;//性别
    /*
    * transient 短暂的
    * 当一个属性被transient修饰,这个对象被序列化时,会自动被忽略
    * 反序列化时,这个属性的值使用默认值
    * */
    private transient String[] othreInfo;//其他信息
    private int salary;//工资
    //生成构造方法
    /* 快捷方式:
        alt+insert,
        右键,选择Generate...,选择Constructor
     */
    public Person(String name, int age, String gender, String[] othreInfo) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.othreInfo = othreInfo;
    }
    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;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String[] getOthreInfo() {
        return othreInfo;
    }
    public void setOthreInfo(String[] othreInfo) {
        this.othreInfo = othreInfo;
    }
    //生成toString方法

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", othreInfo=" + Arrays.toString(othreInfo) +
                ", salary=" + salary +
                '}';
    }
}
2.4.1 OOSDemo案例
package Part02IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * @author 老安
 * @data 2022/4/27 21:11
 * 对象流
 * java.io.ObjectOutputStream和ObjectInputStream
 * 对象流是一对高级流,在流链接中完成对对象与字节转换
 * 即:对象序列化与反序列化
 * 对象 --> 文件 序列化
 * 文件 --> 对象 反序列化
 */
public class OOSDemo {
    public static void main(String[] args) throws IOException {
        String name = "song";
        int age = 18;
        String gender = "男";
        String[] otherInfo = {"是一个帅哥","来自于11","爱好不明","广大妇女之友"};
        Person p = new Person(name, age, gender, otherInfo);
        System.out.println(p);//p.toString()
        FileOutputStream fos = new FileOutputStream("person.obj");
        //创建一个对象输出流,也是序列化流,是一个高级流
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        /*
        * 对象输出流提供的独有的方法 writeObject(Object obj)
        * 会进行对象的序列化,并将对象序列化后的字节通过其连接的流写出
        * */
        oos.writeObject(p);
        System.out.println("写出完毕!!!");
        oos.close();
    }
}
2.4.2 OISDemo案例
package Part02IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * 使用对象输入流进行对象的反序列化
 */
public class OISDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream fis = new FileInputStream("person.obj");
        ObjectInputStream ois = new ObjectInputStream(fis);
        /*
        * 对象输入流中提供了将对象反序列化的方法Object readObject
        * */
        Person p = (Person)ois.readObject();
        System.out.println(p);
        ois.close();
    }
}
2.5 转换字符流  2.5.1 OutputStreamWriter
package Part02IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;

/**
 * java IO 将流按照读写的单位划分为字节流和字符流
 * java.io.InputStream和OutputStream是所有字节输入和输出的超类,最小单位是字节
 * 而java.io.Reader和Writer是所有字符输入和输出的超类,最小单位是字符
 * 因此注意:只适合读取文本数据
 * 字符流的本质还是读写字节只是自动完成了字符和字节的转换
 * 转换流是一对常用的字符流实现类:
 * java.io.InputStreamReader和OutputStreamWriter
 * 这对流是一对高级流,作用两个:
 * 1.在流链接时,衔接其他高级字符流和下面的字节流
 * 2.负责将字符与对应的字节按照指定的字符集自动转换方便读写 *** 作
 */
public class OSWDemo {
    public static void main(String[] args) throws IOException {
        //向文件osw.txt中写入文本数据
        //文件字节输出流(低级流)
        FileOutputStream fos = new FileOutputStream("osw.txt");
//        String line = "我欲成仙,法力无边!";
//        byte[] data = line.getBytes(StandardCharsets.UTF_8);
//        fos.write(data);
        //字节字符转换流(高级流)
        //在创建转换流时,通常需要指定第二个参数,明确使用的字符集
        OutputStreamWriter osw = new OutputStreamWriter(fos,StandardCharsets.UTF_8);
        osw.write("哈哈哈哈哈哈哈哈!");
        osw.write("啦啦啦啦啦啦啦啦!");
        System.out.println("写出完毕!");
        osw.close();
    }
}
2.5.2 InputStreamReader
package Part02IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * 测试转换流读取文本数据
 */
public class ISRDemo {
    public static void main(String[] args) throws IOException {
        //将osw.txt中的所有内容读取出来,并输出到控制台
        //文件字节输入流(低级流)
        FileInputStream fis = new FileInputStream("osw.txt");
        //字符转换流(高级流)
        //InputStreamReader
        InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
        //读取一个字符,返回的int值是一个char
        //但是若返回的是-1,表示读取到了末尾
//        int d = isr.read();
//        System.out.println((char)d);
        int d;
        while ((d=isr.read())!=-1){
            //println 自带换行 print不带换行
            System.out.print((char)d);
        }
        isr.close();

    }
}
2.5.3 缓冲字符流
package Part02IO;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
 * 缓冲字符流
 * java.io.BufferedWriter和BufferedReader
 * 缓冲字符流内部维护了一个数组,可以快读写文本数据来进行读写性能的提升
 * java.io.PrintWriter 具有自动行刷新功能的缓冲字符流输出流,
 * 内部总是链接BufferedWriter
 */
public class PWDemo {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        PrintWriter pw = new PrintWriter("./pw.txt","UTF-8");
        pw.println("哈哈哈哈哈哈哈哈!");
        pw.println("啦啦啦啦啦啦啦啦!");
        System.out.println("写出完毕");
        pw.close();
    }
}
2.5.4 在流链接中使用Printwriter
package Part02IO;

import java.io.*;
import java.util.Scanner;

/**
 * 在流链接中使用PW
 */
public class PWDemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        //文件字节输出流(低级流),向文件中写入字节数据
        FileOutputStream fos = new FileOutputStream("pw2.txt",true);
        //转换输出流(高级流,且是一个字符流),1.衔接字符与字节流 2.将写出的字符转换成字节
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        //缓冲字符输出流(高级流),快读写加快效率
        BufferedWriter bw = new BufferedWriter(osw);
        /*
        * PrintWriter 构造器中,当第一个参数是一个流时,就支持再传入一个boolean参数,
        * 表示是否自动行刷新,当值为true时,就开始自动行刷新功能,也就是
        * 每当我们调用println会自动调用flush方法
        * */
        PrintWriter pw = new PrintWriter(bw,true);
        //完成简易的记事本,控制台输入的每行字符串都按行写入文件,输入exit时,退出
        Scanner scanner = new Scanner(System.in);
        while (true){
            String line = scanner.nextLine();
            //当输入的内容是exit时,不论大小写,就跳出循环
            if ("exit".equalsIgnoreCase(line)){
                break;
            }
            pw.println(line);
        }
        pw.close();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/917111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存