Java Day 10 io流

发布于:2024-03-15 ⋅ 阅读:(71) ⋅ 点赞:(0)

1、前置知识 字符集

1.1 标准ASCII

每个字符一个字节,共128个字符,00000000-01111111(第一位都是0
在这里插入图片描述

1.2 GBK编码

一个中文字符占两个字节,兼容了ASCII编码。
英文,符号数字等仍然是一个字节,每个汉字的第一位都是1。

1.3 UTF-32

每个字符占四个字节,但是这样太浪费空间了。

1.4 UTF-8

可变编码。汉字占3个字节,数字这些占一个字节。
在这里插入图片描述
编码和解码要使用相同的字符集,否则会出现乱码
在这里插入图片描述

1.5 编码和解码方法

Java提供了常用的编码和解码方法
在这里插入图片描述

     String  data="cky崔";
        //1.编码
        byte[] bytes = data.getBytes();//使用系统默认的编码格式
        byte[] gbks = data.getBytes("GBK");//使用特定的字符集编码

        //2.解码
        String s = new String(bytes); //使用系统默认的格式解码
        System.out.println(s);//cky崔
        String gbk1 = new String(gbks);
        System.out.println(gbk1);//cky��  乱码 因为我们使用GBK进行编码,但是却用UTF-8进行解码
        String gbk = new String(gbks, "GBK");//使用特定的格式解码
        System.out.println(gbk);

2、IO流

在这里插入图片描述

2.1 流的分类

在这里插入图片描述
在这里插入图片描述

2.2 FileInputStream

文件字节输入流,是InputStream 字节输入流这个抽象类的一个实现类,可以把文件磁盘中的数据以字节的形式传输到内存中

2.2.1 常用方法

在这里插入图片描述
①read() 每次读取一个字节 并返回该字节的int值 如果没有数据了 返回-1
②每次读取一个字节 性能差 因为IO会利用硬件资源 时间慢 且一次读取一个字节,读取中文时 会乱码
③每次读取多个字节 返回读取的字节数 这里每次读取3个字节
④这种一次读取多个字符,虽然性能得到了提升,但是读取中文时还是会出现乱码问题

package com.cky.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

public class Endecode {
    public static void main(String[] args) throws Exception {
   // 1、创建字节文件输入流的管道 以及它要连通的文件
//        InputStream fileInputStream = new FileInputStream(new File("E:\\java_code\\project\\hello-app\\a.txt"));

        //简化写法  直接写路径即可 没必要new一个文件对象
        InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");
        int c;

        //read() 每次读取一个字节 并返回该字节的int值 如果没有数据了 返回-1
//        while((c=fis.read())!=-1){
//            System.out.print((char)(c));
//        }
        //每次读取一个字节 性能差 因为IO会利用硬件资源 时间慢 且一次读取一个字节,读取中文时 会乱码

        //每次读取多个字节  返回读取的字节数  这里每次读取3个字节
        //这种一次读取多个字符,虽然性能得到了提升,但是读取中文时还是会出现乱码问题
        byte[] bytes = new byte[3];
        int len;  //读取的内容保存在bytes数组中 该数组会重复利用
        while((len=fis.read(bytes))!=-1){
            //读取多少 倒出多少
            String s = new String(bytes,0,len); //最后可能并不会读取刚刚好的字符,这里我们只用解码刚好读入的字节数就可以,如果没有读满,然后全部解码,就会出现内容不一致
            System.out.print(s);}
            fis.close();//释放资源
    }}


将文件的全部内容一次读取如果文件很大,则无法操作

方法1

        //简化写法  直接写路径即可 没必要new一个文件对象
        InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");
        //使用文件字节输入流 一次读取文件全部字节
        File file = new File("E:\\java_code\\project\\hello-app\\a.txt");
        long len=file.length(); //文件是系统资源 存放在硬盘中 可能会很大 所以是long类型
        byte[] bytes = new byte[(int)len]; //因为是要将文件内容 读取到内容中 内存空间有限 所以都是int类型
        int read = fis.read(bytes);
        String s = new String(bytes);
        System.out.println(s);
        fis.close();//释放资源

方法2

        InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");
        byte[] bytes = fis.readAllBytes();
        String s = new String(bytes);
        System.out.println(s);
        fis.close();//释放资源

在这里插入图片描述

2.3 FileOutputStram

文件字节输出流
在这里插入图片描述

2.3.1 常用方法

在这里插入图片描述

package com.cky.file;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Endecode {
    public static void main(String[] args) throws Exception {
        // 构建文件字节输出流对象 并且确定与哪个文件相连
        //该文件可以不存在 如果不存在 会自动创建
        //默认会覆盖原来的文件 会先清空再写 每次创建一次流对象均是如此
        //如果想要追加,在后边添加true
//        OutputStream fileOutputStream = new FileOutputStream("D:/a.txt");
        OutputStream fileOutputStream = new FileOutputStream("D:/a.txt",true);

        fileOutputStream.write(97);//一次添加一个字节
        fileOutputStream.write('a');
        byte[] bytes = "abc崔".getBytes();//一次添加多个字节
        fileOutputStream.write(bytes);

        fileOutputStream.write("\r\n".getBytes());  //"\r\n" 可以适应各个系统 \n只适用于windows

        fileOutputStream.close();//释放资源
    }}




2.3.2 文件复制案例

在这里插入图片描述

package com.cky.file;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Endecode {
    public static void main(String[] args) throws Exception {
      //照片复制

        //1、创建一个文件输入流 与原文件相连
        InputStream inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");
        //2、创建一个文件输出流 与复制文件 相连
        OutputStream outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");

        //创建一个字符数组 用于缓存我们读取到的数据

        byte[] bytes = new byte[1024];

        int len;//用于记录我们读取到了多少 字节数据

        while ((len=inputStream.read(bytes))!=-1){
            //读多少 写多少
            outputStream.write(bytes,0,len);
        }
        outputStream.close();
        inputStream.close();

        System.out.println("复制成功");
    }}


2.4 释放资源的方式

2.4.1 try-catch-finally

//最后要释放资源 防止在未释放资源之前 发生异常
//在释放资源之前先要判断是否为空 防止在未创建之前 发生异常

package com.cky.file;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Endecode {
    public static void main(String[] args) throws Exception {
      //最后要释放资源 防止在未释放资源之前 发生异常 
        InputStream inputStream=null;
        OutputStream outputStream=null;
        

        try {
            //1、创建一个文件输入流 与原文件相连
            inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");
            //2、创建一个文件输出流 与复制文件 相连
            outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");

            //创建一个字符数组 用于缓存我们读取到的数据

            byte[] bytes = new byte[1024];

            int len;//用于记录我们读取到了多少 字节数据

            while ((len=inputStream.read(bytes))!=-1){
                //读多少 写多少
                outputStream.write(bytes,0,len);
            }
            outputStream.close();
            inputStream.close();

            System.out.println("复制成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            
            //先要判断是否为空 防止在未创建之前 发生异常
            if (inputStream!=null)
                inputStream.close();
            if (outputStream!=null)
                outputStream.close();
        }
    }}


2.4.2 try-with-resource

在这里插入图片描述

这种更简洁 会自动释放资源
为了说明会自动调用 close方法 这里我们自己定义了一个资源

package com.cky.file;

public class Myresource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("close方法被执行");
    }
}

package com.cky.file;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Endecode {
    public static void main(String[] args) throws Exception {
      //最后要释放资源 防止在未释放资源之前 发生异常


        try ( InputStream inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");
        //这里只能放置资源对象
         //什么是资源?资源 会实现AutoCloseable接口 并且会有一个close方法。
        //用完之后会自动调用close 方法
       OutputStream outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");
       Myresource myresource=new Myresource()){

            byte[] bytes = new byte[1024];

            int len;//用于记录我们读取到了多少 字节数据

            while ((len=inputStream.read(bytes))!=-1){
                //读多少 写多少
                outputStream.write(bytes,0,len);
            }
            System.out.println("复制完成");

        } catch (IOException e) {
            e.printStackTrace();
        }


    }}

结果:
复制完成
close方法被执行

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到