首页 > 其他分享 >File类与IO流 3

File类与IO流 3

时间:2023-09-09 14:13:54浏览次数:32  
标签:字符 IO File new 序列化 public String

File类与IO流 3

03-缓中流的使用.

1.基础I0流的框架

抽象基类 4个节点流〔也称为文件流) 4个缓冲流(处理流的一种)
InputStream FileInputStream BufferedInputStream
outputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter

2.缓冲流的作用:

提升文件读写的效率。

3.

4个缓冲流 使用的方法
处理非文本文件的字节流:
BufferedInputStream read(byte[ ] buffer)
BufferedOutputStream write(byte[] buffer ,0,len) /flush()
处理文本文件的字符流:
BufferedReader read(char[] cBuffer)/readLine()
BufferedWriter write(char[] cBuffer,0,len) /write(String) /flush()

try之前

    //需求:使用BufferedInputStream \ BufferedOutputStream复制一个图片
    public void test2() {

        //1.创建File类的对象  2个
        File srcFile = new File("playgirl.jpg");
        File destFile = new File("playgirl_copy1.jpg");
        //2.创建相关的字节流、缓冲流
        FileInputStream fileInputStream = new FileInputStream(srcFile);
        FileOutputStream fileOutputStream = new FileOutputStream(destFile);

        BufferedInputStream bis = new BufferedInputStream(fileInputStream);
        BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
        //3.数据的读入和写出的过程
        byte[] buffer = new byte[1024];//1kb
        int len;//记录每次读入到buffer中的字节的个数
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);//写入byte[] buffer的从0到len字符,左闭右开
        }

        //4.关闭流资源

        //外层的流的关闭
        //由于外层流的关闭也会自动的对内层的流进行关闭操作。所以可以省略内层流的关闭。

        bos.close();
        bis.close();
        //内层的流的关闭
//        fileOutputStream.close();
//        fileInputStream.close();

    }

readLine()

   //使用BufferedReader将hello.txt中的内容显式在控制台上。
    public void test4() throws IOException {
        File file = new File("hello.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));
        ///读取的过程
        ///方式1: read(char[ ] cBuffer)
//        char[] cBuffer = new char[1024];
//        int len;
//        while ((len=br.read(cBuffer))!=-1){
//            //方法1
////            for (int i = 0; i < len; i++) {
////                System.out.print(cBuffer[i]);
////            }
//            //方法2
//            String s = new String(cBuffer, 0, len);
//            System.out.print(s);
//        }
        //方式2: readLine(),:每次读取一行文本中的数据。返回的字符串是不包含换行符的。
        String data;
        while ((data=br.readLine())!=null){
            System.out.println(data);
        }

        br.close();
    }
//使用BufferedReader和BufferedWriter实现文本文件的复制
    //注意:开发中,还是需要使用try-catch-finally来处理流的异常。

    public void test5() throws IOException {
    //1.造文件,造流
        File file = new File("hello.txt");
        File file1 = new File("hello_copy1.txt");
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file1));

        //2. 文件的读写操作
        String data;
        while ((data=bufferedReader.readLine())!=null){
            bufferedWriter.write(data+"\n");
            //System.out.println();这是控制台换行
            bufferedWriter.newLine();//表示换行操作

            bufferedWriter.flush();//刷新的方法。每当调用此方法时,就会主动的将内存中的数据写出到磁盘文件中。

        }
        //3. 关闭资源,会自动刷新
        bufferedWriter.close();
        bufferedReader.close();
    }

04-转换流的使用.

字符编码:字符、字符串、字符数组--->字节、字节数组(从我们能看得懂的--->我们看不懂的)

字符解码:字节、字节数组--->字符、字符串、字符数组(从我们看不懂的--->我们能看得懂的

2.如果希望程序在读取文本文件时,不出现乱码,需要注意什么?

  • 解码时使用的字符集必须与当初编码时使用的字符集得相同。
  • 拓展:解码集必须要与编码集兼容。比如:文件编码使用的是GBK,解码时使用的是utf-8。如果文件中只有abc等英文字符,此情况下
    也不会出现乱码。因为GBK和utf-8都向下兼容了ASCII (或ascii)

3.转换流:

作用:实现字节与字符之间的转换

API:
InputStreamReader:将一个输入型的字节流转换为输入型的字符流。outputStreamWriter:将一个输出型的字符流转换为输出型的字节流。

public void test1(){
//
File file1 = new File( pathname: "dbcp_utf-8.txt" );
//
FileInputStream fis = new EileInputStneam(file1);InputStreamReader isr = new InputStreamReader(fis);//此时使用的是IDEA默认的UTF-8的字符集

char[ ] cBuffer = new char[1024];
int len;
while((len = isr.nead(cBuffer)) != -1){
String str = new String(cBuffer,offset: 0,len) ;
system.out.print(str);
//关闭资源
    isr.close(;

读取到的数据出现了乱码。
因为dbcp_utf-8.txt文件使用的是utf-8的字符集进行的编码,所以在读取此文件时使用的解码集必须也是utf-8,否则会出现乱码!

需求:将gbk格式的文件转换为utf-8格式的文件存储。
public void test4(){
/ /1.造文件
File file1 = new File( pathname: "dbcp_gbk.txt" );
File file2 = new File( pathname: "dbcp_gbk_to_utf8.txt" );
//2.造流
FileInputStream fis = new Eil.eInputs.tneam(file1);/参数2对应的是解码集,必须与dbcp_gbk.txt的编码集一致。
InputStreamReader isr = new InputStreamReader(fis,charsetName: "GBK");
File0utputStream fos = new File0utputStneam(file2);
outputStreamWriter o0s = new 0utputStreamWriter(fos,charsetName: "utf8");//参数2指明内存中的字符存储到文件中的字节过程中使用的编码集。

    
//3.读写过程
char[] cBuffer = new char[ 1024];int len;
while((len = isr.nead(cBuffer)) != -1){
oos. write(cBuffer, off:0, len) ;
}
system.out.println("操作完成");
//4.关闭资源
oos.close();
    isr.close();

4.关于字符集的理解

4.1在存储的文件中的字符:

  • ascii:主要用来存储a、b、c等英文字符和1、2、3、常用的标点符号。每个字符占用1个字节。
  • iso-8859-1:了解,每个字符占用1个字节。向下兼容ascii。
  • gbk:用来存储中文简体繁体、a、b、c等英文字符和1、2、3、常用的标点符号等字符。
    中文字符使用2个字节存储的。向下兼容ascii,意味着英文字符、1、2、3、标点符号仍使用1个字节。
  • utf-8:可以用来存储世界范围内主要的语言的所有的字符。使用1-4个不等的字节表示一个字符。
    中文字符使用3个字节存储的。向下兼容ascii,意味着英文字符、1、2、3、标点符号仍使用1个字节。

4.2在内存中的字符:

一个字符(char)占用2个字节。在内存中使用的字符集称为Unicode字符集。


1.数据流及其作用(了解)
DataOutputStream:可以将内存中的基本数据类型的变量、String类型的变量写出到具体的文件中。DataInputStream:将文件中保存的数据还原为内存中的基本数据类型的变量、String类型的变量。

2.对象流及其作用

2.1 API:

0bjectInputsteam

0bject0utputStream

2.2作用:

可以读写基本数据类型的变量、引用数据类型的变量。

3.对象的序列化机制是什么

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

4.如下两个过程使用的流:

  • 序列化过程:使用ObjectoutputStream流实现。将内存中的Java对象保存在文件中或通过网络传输出去
  • 反序列化过程:使用0bjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
   //序列号过程
    public void test1() throws IOException {
    //
        File file = new File("object.txt");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));

        //
        oos.writeUTF("江山如此多娇,引无数英雄竞折腰");
        oos.flush();
        oos.writeObject("轻轻的我走了,正如我轻轻的来");
        oos.flush();

        oos.close();
    }

    //反序列化过程:使用ObjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
    public void test2() throws IOException, ClassNotFoundException {
    //
        File file = new File("object.txt");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

        //2.读取文件中的对象(或反序列化的过程)
        String s1 = ois.readUTF();
        System.out.println(s1);

        Object o = ois.readObject();
        System.out.println(o);
        //
        ois.close();

    }

5.自定义类要想实现序列化机制,需要满足:

  • 自定义类需要实现接口:Serializable
  • 要求自定义类声明一个全局常量:static final long serialVersionUID = 42234234L; 用来唯一的标识当前的类。
  • 要求自定义类的各个属性也必须是可序列化的。
    • 对于基本数据类型的属性:默认就是可以序列化的
    • 对于引用数据类型的属性:要求实现Serializable接口

6.注意点:

  • 如果不声明全局常量serialVersionUID,系统会自动声明生成一个针对于当前类的serialVersionUID。如果修改此类的话,会导致serialVersionUID变化,进而导致反序列化时,出现InvalidClassException异常。
  • 类中的属性如果声明为transient或static,则不会实现序列化。
package demo01;

import java.io.Serializable;

public class Person implements Serializable {// Serializable:属于一个标识接口,没有重写方法

    static final long serialVersionUID = 42234234534L;
    transient String name;
    static int age;
    Account account;

    public Person() {
    }

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

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

    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 +
                ", account=" + account +
                '}';
    }
}

class Account implements Serializable {
    static final long serialVersionUID = 422388834534L;
    double balance;

    public Account() {
    }

    public Account(double balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "balance=" + balance +
                '}';
    }
}

======
        //演示自定义类的对象的序列化和反序列化过程
    // 序列化过程:
    public void test3() throws IOException {
        File file = new File("object1.dat");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));

        //2.写出数据即为序列化的过程
        Person p1 = new Person("tom", 22);
        oos.writeObject(p1);
        oos.flush();
        Person p2 = new Person("mmm", 11,new Account(2000));
        oos.writeObject(p2);
        oos.flush();

        oos.close();
    }


    //反序列化过程:使用ObjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
    public void test4() throws IOException, ClassNotFoundException {
        //
        File file = new File("object1.dat");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

        //2.读取文件中的对象(或反序列化的过程)
        Person person= (Person) ois.readObject();
        System.out.println(person);
        Person person1= (Person) ois.readObject();
        System.out.println(person1);
        //
        ois.close();

    }

06-其它流的使用

1.标准输入、输出流

system.in:标准的输入流,默认从键盘输入
system.out:标准的输出流,默认从显示器输出(理解为控制台输出)

通过调用如下的方法,修改输入流和输出流的位置
setIn(InputStream is)
setOut(PrintStream ps)

    public void test1() throws FileNotFoundException {
        PrintStream ps = new PrintStream("info.txt" );
        ps.println( "hello" );
        ps.println(1);
        ps.println(1.5);
        System.setOut(ps);
        System.out.println("你好,atguigu " );
        ps.close();

    }

标签:字符,IO,File,new,序列化,public,String
From: https://www.cnblogs.com/xin-zhi-suo-xiang/p/17689401.html

相关文章

  • [web] Session原理 (转载)
    1SessionWeb三大概念:cookie,session,applicationSession(会话):记录一系列状态用户登录用户登录后的操作Session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。解释session:当用户访问服务器某个网页时,服......
  • Visual Studio Code:代码编辑与开发的全能工具
    在现代软件开发中,一个高效且强大的代码编辑工具是不可或缺的。VisualStudioCode(简称VSCode)作为一款免费开源的代码编辑器,以其丰富的功能和活跃的社区受到了广大开发者的喜爱。本文将介绍VSCode的基本用法和主要特点,帮助您更好地使用这个强大的开发工具。VisualStudioCode简介......
  • Boost.Asio网络库 学习笔记
    Asio网络库学习笔记Boost官网:https://www.boost.org/Boost库许可证://CopyrightJoeCoder2004-2006.//DistributedundertheBoostSoftwareLicense,Version1.0.//(SeeaccompanyingfileLICENSE_1_0.txtorcopyat//https://www.boos......
  • 第十七章 IO流
    17.1IO流的概念IO就是Input和Output的简写,也就是输入和输出的含义。IO流就是指读写数据时像流水一样从一端流到另外一端,因此得名为“流"。17.2基本分类按照读写数据的基本单位不同,分为字节流和字符流。其中字节流主要指以字节为单位进行数据读写的流,可以读写任意类型的......
  • 【笔记】在线凸优化 - Ch1. Introduction
    1.1TheOnlineConvexOptimizationSetting在线凸优化Onlineconvexoptimization(OCO),是一个带有博弈论、统计学习、凸优化的新玩意给出如下问题叙述:考虑一种博弈游戏,回合制,第\(t\in[T]\)回合,先由玩家从决策集\({\calK}\in\mathbb{R}^n\)中选择一个决策\({\bfx}......
  • ​DockerFile简介+镜像构建
    1)Dockerfile简介由一系列命令和参数构建成的脚本构建三步骤编写Dockerfile文件==>dockerbuild(打包为镜像)==>dockerrun1)每条保留字指令都必须为大写字母且后面要跟随至少一个参数。2)指令按照从上到下的顺序执行3)#表示注释4)每条指令都会创建一个新的镜像层,并对镜像进行提交2......
  • dockerfile entrypoint cmd 同时使用
    CMD与ENTRYPOINT都是用于指定启动容器执行的命令,区别在于:当dockerrun命令中有参数时,守护进程会忽略CMD命令。使用ENTRYPOINT指令不会忽略,并且会接收dockerrun参数附加到命令行中。dockerrun的命令,相当于新加的CMD,会覆盖原有的CMDnginx的镜像就是这样。dockerrun......
  • but Android SDK not found at this location.
    ENVPATH里设置好, SDKMANAGER路径要保持一致。这个是常规操作。还有个隐藏操作: SDKMANGERTOOLS里,点取消 hideobse.... 然后安装 AndroidSDKtools 添加path:sdk里的 D:\android_sdk\tools  D:\android_sdk\platform-tools 还要重启电脑!!!!!!解决。 ......
  • pytest运行警告问题解决:DeprecationWarning: pkg_resources is deprecated as an API
    前言最近在运行pytest的时候,经常出现这个警告DeprecationWarning:pkg_resourcesisdeprecatedasanAPISeehttps://setuptools.pypa.io/en/latest/pkg_resources.htmlfrompkg_resourcesimportiter_entry_points从警告上看是方法被弃用,肯定是因为新版弃用了旧版的语法。......
  • Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,
    一、概述今天同事突然询问报错Illegalmixofcollations(utf8mb4_general_ci,IMPLICIT)and(utf8mb4_0900_ai_ci,IMPLICIT)foroperation'='分析:应该是连表查询,两张表的的匹配列编码格式不一致引起的二、问题复现1、创建两张小表createtabletest1(namevarchar(10)C......