首页 > 编程语言 >Java基础复习—— IO流2

Java基础复习—— IO流2

时间:2023-07-23 23:22:24浏览次数:36  
标签:Java 复习 System String IO new 序列化 public out

IO流

节点流和处理流

  1. 节点流可以从一个特点的数据源读写数据,如FileReader、FileWriter

image

  1. 处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、.BufferedWriter

image

区别和联系

  • 节点流是底层流(低级流),直接和数据源相连接。
  • 处理流(包装流)对节点流进行了包装,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
  • 处理流对节点流进行了包装,使用了修饰器的设计模式,不会直接与数据源相连接。

image

处理流的特点:

  • 性能的提高:主要以增加缓冲的方式来提高输入输出的效率

  • 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

处理流 - BufferedReader 和 BufferedWriter

  • BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的

  • 关闭时处理流,只需要关闭外层流即可

应用案例

1.使用BufferedReader读取文本文件,并显示在控制台

@Test
    public void m1() {
//        String filePath = "F:\\VSCode\\JAVA\\file\\test\\FileWriter.test";
        String filePath = "F:\\VSCode\\JAVA\\file\\test\\the Zen of Python.txt";
        BufferedReader bufferedReader = null;
        String line;
        try {
            bufferedReader = new BufferedReader(new FileReader(filePath));
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }

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

应用案例

使用BufferedWriter写入到文件

 @Test
    public void m2() throws IOException {

        String filePath = "F:\\VSCode\\JAVA\\file\\test01\\a.txt";

        BufferedWriter writer = new BufferedWriter(new FileWriter(filePath));

        writer.write("墨染启明,hello");
        writer.newLine();
        writer.write("墨染启明,hello");
        writer.newLine();
        writer.write("墨染启明,hello");
        writer.newLine();

        writer.close();
    }

应用案例

综合使用 BufferedReader 和 BufferedWriter 完成文本文件拷贝

public class Copy01 {
    // 1. BufferedReader 和 BufferedWriter 是按照字符操作
	//2. 不要去操作 二进制文件[声音, 视频, doc, pdf ], 可能造成文件损坏
    public static void main(String[] args) throws IOException {
        String src = "F:\\VSCode\\JAVA\\file\\test\\the Zen of Python.txt";
        String dest = "F:\\VSCode\\JAVA\\file\\test02\\b.txt";

        copy(src, dest);
    }

    public static void copy(String srcPath, String destPath) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(srcPath));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(destPath));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            bufferedWriter.write(line);
            bufferedWriter.newLine();
        }

        bufferedWriter.close();
        bufferedReader.close();
    }
}

处理流-BufferedInputStream 和 BufferedOutputStream

  • BufferedInputStream 是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组。
  • BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

应用案例

编程完成圈片/音乐的拷贝(要求使用Buffered.流)

public class Copy02 {
    public static void main(String[] args) {

        String srcPath = "F:\\VSCode\\JAVA\\file\\test\\No One But You.mp3";
        String destPath = "F:\\VSCode\\JAVA\\file\\test03\\copy.mp3";
        copy02(srcPath, destPath);
    }

    public static void copy02(String scr, String dest) {
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        byte[] bytes = new byte[16];
        int len;

        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(scr));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(dest));

            while ((len = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedOutputStream.close();
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

对象流-ObjectInputStream 和 ObjectOutputStream

看一个需求

  1. 将int num=100这个int数据保存到文件中,注意不是100数字,而是int 100,并且,能够从文件中直接恢复int 100

  2. Dog dog=new Dog(“小黄”,3)这个dog对像保存到文件中,并且能够从文件恢复.

  3. 上面的要求,就是能够将基本数据类型或者对象进行序列化和反序列化操作

序列化和反序列化

  1. 序列化就是在保存数据时,保存数据的值数据类型

  2. 反序列化就是在恢复数据时,恢复数据的值和数据类型

  3. 需要让某个对像支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

    • Serializable/这是一个标记接口,没有方法
    • Externalizable该接口有方法需要实现,因此我们一般实现上面的Serializable接口

对象流的介绍

功能:提供了对基本类型或对象类型的序列化和反序列化的方法

ObjectOutputStream:提供序列化功能

ObjectInputStream:提供反序列化功能

注意事项和细节说明

  1. 读写顺序要一致
  2. 要求序列化或反序列化对像,需要实现Serializable
  3. 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
  4. 个序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口
  6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
public class ObjectOutStream01 {
    public static void main(String[] args) throws IOException {
        // 序列化后,保存的文件格式,不是存文本,而是按照他的格式来保存
        String filePath = "F:\\VSCode\\JAVA\\file\\test03\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        // 序列化数据到 e:\\data.dat
        oos.writeInt(100); // int-->Integer(实现了serializable接口)
        oos.writeBoolean(true); // boolean --> Boolean(实现了serializable接口)

        oos.writeChar('a'); // char -- > Character (实现了serializable接口)
        oos.writeDouble(3.14); // double --> Double (实现了serializable接口)
        oos.writeUTF("墨染启明"); // String(实现了serializable接口)
        //  保存一个Dog 对象
        oos.writeObject(new Dog(3, "wangcai", "yello", "Japan"));

        oos.close();
        System.out.println("数据保存完毕(序列化形式)");

    }
}


// 如果需要序列化某个类的对象,实现Serializable接口
class Dog implements Serializable {
    private int age;
    private String name;
    //serialVersionUID 序列化的版本号,可以兼容性
    private static final long serialVersionUID = 1L;

    private transient String color;
    private static String nation;

    private Master master = new Master();

    public Dog(int age, String name, String color, String nation) {
        this.age = age;
        this.name = name;
        this.color = color;
        this.nation = nation;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", nation='" + nation + '\'' +
                ", master='" + master + '\'' +
                '}';
    }
}

class Master implements Serializable{}  // 属性需要序列化
public class ObjectInputSteam01 {
    public static void main(String[] args) throws Exception{
        String filePath = "F:\\VSCode\\JAVA\\file\\test03\\data.dat";

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

        // 读取
        // 1.读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致

        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        Object o = ois.readObject();
        System.out.println(o.getClass());
        System.out.println("dog= " + o); // 底层 Object -- Dog

        ois.close();
    }
}

标准输入输出流

类型 默认设备
System.in 标准输入 InjputStream 键盘
System.out 标准输出 PrintStream 显示器
public static void main(String[] args) {
        // 标准输入 键盘
        // System类 的public final static InputStream in = null
        // System.in 编译类型:InputStream
        // System.in 运行类型:BufferedInputStream
        System.out.println(System.in.getClass()); // class java.io.BufferedInputStream

        // 标准输出 显示器
        // System.out       public final static PrintStream out = null;
        // System.out 编译类型:PrintStream
        // System.out 运行类型:PrintStream
        System.out.println(System.out.getClass()); //class java.io.PrintStream


        System.out.println("hello");

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入内容");
        String next = scanner.next();
        System.out.println(next);

    }

转换流 InputStreamReader 和 OutputStreamWriter

  1. InputStreamReader:Readert的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
  2. OutputStreamWriter:Writert的子类,实现将OutputStream(字节流)包装成Writer(字符流)
  3. 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
  4. 可以在使用时指定编码格式(比如utf-8,gbk,gb2312,1S08859-1等)

应用案例

需程将字节流Filelnputstream包装成转换成字符流InputStreamReader,对文件进行读取(按照utf-8/gbk格式),进而在包装成BufferedReader

public class InputStreamReader01 {
    public static void main(String[] args) throws Exception {
        String filePath = "F:\\VSCode\\JAVA\\file\\test03\\a.txt";

        // 1.new FileInputStream(filePath) -->转成  InputStreamReader
//        InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
//        InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "utf-8"); // 乱码
        // 2.指定编码为 gbk
        // 3. 把 InputStreamReader 传入 BufferedReader
//        BufferedReader br = new BufferedReader(isr);

        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));

        String s = br.readLine();
        System.out.println(s);

        br.close();
    }
}
public class OutputStreamWriter01 {
    public static void main(String[] args) throws IOException {
        String filePath = "F:\\VSCode\\JAVA\\file\\test02\\b.txt";
//        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), "gbk"));
        // 默认 utf-8
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), StandardCharsets.UTF_16));
        bufferedWriter.write("墨染启明");

        bufferedWriter.close();
    }
}

打印流 PrintStream 和 PrintWriter

打印流只有输出流,没有输入流

public class PrintWriter01 {

    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter printWriter = new PrintWriter(System.out);
//        PrintWriter printWriter = new PrintWriter("F:\\VSCode\\JAVA\\file\\test03\\c.txt");
        printWriter.print("hi, 北京你好");
        printWriter.close(); // flush + 关闭流
    }
} 
public class PrintStream01 {
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;
        // 默认情况下,PrintStream 输出数据的位置 是 标准输出,即显示器
        out.println("jack");
        /*
        public void print(String s) {
             if (s == null) {
                 s = "null";
        }
             write(s);
        }
        *
        *
        * */
        out.write("hello".getBytes());
        System.out.write("xxxx".getBytes(StandardCharsets.UTF_8));

        out.close();
        // 可以修改打印流的输出位置
        System.setOut(new PrintStream("F:\\VSCode\\JAVA\\file\\test03\\print.txt"));
        System.out.println("sunday"); // 输出到该文件

//        System.setOut();
        System.out.println("Monday");
    }
}

Properties 类

如下一个配置文件mysql.properties

ip=192.168.0.13

user=root

pwd=12345

请问编程读取ip、user和pwd的值是多少

分析

1.传统的方法

2.使用Properties类可以方便实现

public class Properties01 {
    public static void main(String[] args) throws IOException {
        String filePath = "F:\\VSCode\\JAVA\\file\\test03\\mysql.properties";

        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            String[] split = line.split("=");
            //  如果要求拿到ip
            if ("ip".equals(split[0])) {
                System.out.println(split[0] + " 的值是:" + split[1]);
            }
        }

        bufferedReader.close();

    }
}

基本介绍

  • 专门用于读写配置文件的集合类

  • 配置文件的格式:

    键=值

    键=值

  • 注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String

Properties的常见方法

  • Ioad:加载配置文件的键值对到Propertiesi对象

  • list:将数据显示到指定设备

  • getProperty(key):根据键获取值

  • setProperty(key,value):设置键值对到Properties对象

  • store:将Propertiest中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码

String	getProperty(String key)
Searches for the property with the specified key in this property list.
String	getProperty(String key, String defaultValue)
Searches for the property with the specified key in this property list.
    
void	list(PrintStream out)
Prints this property list out to the specified output stream.
void	list(PrintWriter out)
Prints this property list out to the specified output stream.
    
void	load(InputStream inStream)
Reads a property list (key and element pairs) from the input byte stream.
void	load(Reader reader)
Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.
    
void	save(OutputStream out, String comments)
Deprecated. 
This method does not throw an IOException if an I/O error occurs while saving the property list. The preferred way to save a properties list is via the store(OutputStream out, String comments) method or the storeToXML(OutputStream os, String comment) method.
    
Object	setProperty(String key, String value)
Calls the Hashtable method put.
    
void	store(OutputStream out, String comments)
Writes this property list (key and element pairs) in this Properties table to the output stream in a format suitable for loading into a Properties table using the load(InputStream) method.
void	store(Writer writer, String comments)
Writes this property list (key and element pairs) in this Properties table to the output character stream in a format suitable for using the load(Reader) method.

image-20230723225610231

  public static void main(String[] args) throws IOException {
        // 使用Properties 类来读取

        // 1.创建Properties 对象
        Properties properties = new Properties();
        // 2. 加载指定的配置文件
        properties.load(new FileReader("F:\\VSCode\\JAVA\\file\\test03\\mysql.properties"));
        // 3. 把k-v显示在控制台
        properties.list(System.out);
        // 4. 根据key 获取对应的值
        String user = properties.getProperty("user");
        String pwd = properties.getProperty("pwd");
        System.out.println(user + " 的密码: " + pwd);


    }
public static void main(String[] args) throws IOException {
        // 使用Properties 类来创建配置文件,修改配置文件内容
        Properties properties = new Properties();
        // 创建
        properties.setProperty("charset", "utf-8");
        properties.setProperty("user", "杰克"); // 中文的unicode码
        properties.setProperty("pwd", "abc111");

        properties.setProperty("pwd", "123abc");
        // 将k-v保存到文件中即可
        properties.store(new FileOutputStream("F:\\VSCode\\JAVA\\file\\test03\\mysql01.properties" ),"hello这是注释");


        System.out.println("保存配置文件成功");
    }

标签:Java,复习,System,String,IO,new,序列化,public,out
From: https://www.cnblogs.com/ai135/p/17576181.html

相关文章

  • java深浅拷贝
    对于Java拷贝的理解在java语言中,当我们需要拷贝一个对象的时候,常见的会有两种方式的拷贝:深拷贝和浅拷贝。浅拷贝只是拷贝了原对象的地址,所以原对象的任何值发生改变的时候,拷贝对象的值也会随之而发生变化。拿地址。深拷贝则是拷贝源对象的所有值而不是地址,所以即源......
  • 牛客周赛Round4(java)
     Java组代码importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);intn=scanner.nextInt();intm=scanner.nextInt();StringBuildersb=newStringB......
  • SAP ABAP 系统里和传输请求读写相关的 Function Module
    在SAPABAP系统中,有一系列的函数模块以TRINT开头,被用来与TransportRequest交互。这里的"TRINT"并不是一个标准的缩写,它主要被用来表明这个函数模块与TransportRequest有关。在"TRINT"中,"TR"很明显的指的是"TransportRequest",而"INT"可能是"Interface"或&qu......
  • WPF Syncfusion控件(图表部分)简介
    一周之前就打算也这篇文章了,但由于非常忙最近,家里的事情很多。周日晚上忙完所有事情,终于有自己的时间,于是决定完成这篇文章,不能再拖了!本文主要是给读者起到一个知道怎么去阅读demo的作用,如果在实际开发中读者需要使用到syncfusion,务必仔细阅读官方文档中所提供的demo。写之前......
  • 深入理解 SAP Fiori Front-end Server 试读版
    从本质上说,SAPFioriFront-endServer(在SAP官方文档里经常缩写为SAPFES)是ABAP应用服务器的一个Addon.Addon是SAPABAP一个特有的概念,是一种专门设计用于扩展SAPABAP系统基本功能的软件组件。大家可以把Addon理解成逻辑上具有关联关系的,聚合在一起,共同实现一个......
  • 什么是 SAP ABAP 系统中类型为 Relocations 的传输请求
    在SAPABAP系统里,事务码SE10中的RelocationsRequestType用于在不同的SAP系统之间移动开发对象。它有以下三种类型:Relocationswithoutpackagechange:这种类型的请求允许开发人员在临时基础上在另一个SAP系统中开发对象。例如,一种需求是可能希望在单独的SAP系统......
  • springboot获取ApplicationContext的两种方式
    方法1:启动类返回的就是个ApplicationContext对象,可以把这个对象存在当前类的静态变量中;方法2:写个工具类,实现ApplicationContextAware接口,实现默认方法setApplicationContext,传入的参数即applicationContext,找个地方存放即可......
  • 什么是软件开发领域的 deprecation
    在软件开发中,“Deprecation”或者说“弃用”是一个重要的概念。当一个特定的特性、函数或方法在以后的版本中不再被推荐使用,甚至可能在未来的版本中被移除,这样的特性、函数或方法就被称为已被弃用的(deprecated)。弃用是一个渐进的过程,旨在向开发者提供充足的时间来调整他们的代码,......
  • nodejs sqlite报错 typeorm[ Expression tree is too large (maximum depth 1000)]
    最近在给公司开发一个工具时,使用SQLite,然后突然发现报错:(node:16195)UnhandledPromiseRejectionWarning:QueryFailedError:SQLITE_ERROR:Expressiontreeistoolarge(maximumdepth1000)athandler(/snapshot/server-work/node_modules/typeorm/driver/sqlite/Sql......
  • 什么是前端开发领域的 visual degradation
    VisualDegradation在前端开发领域中,通常被理解为一种策略,这种策略允许网站或网络应用在不同的浏览器、设备或网络条件下以不同的视觉质量呈现,而不会丧失核心功能。这种策略可以确保所有用户,无论他们的设备或网络条件如何,都能够访问和使用网站或网络应用的主要功能。这并不意味......