IO流中的字符,字节和缓冲流

本文详细介绍Java中的IO流技术,包括输入输出流的概念、字节流与字符流的区别、节点流和处理流的作用,并通过具体案例演示了文件读写、复制的操作方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流:用来操作文件内容的技术,IO流(输入输出):输入输出都是针对于程序而言的

	IO分类:

  	  1.按照数据流向分:输入输出流
        输入流:将文件中的内容读取到程序中
        输出流:将程序中的数据写到文件中

   	 2.按照数据类型:字节流/字符流
        字节流:以字节为单位进行的
        字符流:以字符为单位进行的,操作中文字符更方便

        输入流     输出流
        字节流     字符流
        字节输入流(InputStream)   字节输出流(OutputStream)
        字符输入流(Reader)读       字符输出流(Writer)写

    3.按照流的角色:节点流  处理流
        节点流:程序用于直接操作目标设备所对应的流
                例如:程序用于直接操作文件对应的流;文件流是一种直接用于操作文件的节点流
                文件字符输入流(FileReader)读  文件字节输入流(FileInputStream)
                文件字符输出流(FileWriter)写  文件字节输出流(FileOutputStream)

         处理流:通过一个间接流去调用节点流,以达到更加灵活方法的读写操作,
            这个间接的流就是处理流
            Buffered缓冲流是一种处理流,
            缓冲字符输入流 BufferedReader      缓冲字节输入流 BufferedInputStream
            缓冲字节输出流 BufferedWriter      缓冲字节输出流 BufferedOutputStream

           1.缓冲流不能直接操作文件,必须包装文件流,通过文件流访问
           2.缓冲流的效率要比文件缓流效率高


            涉及到流,直接按照这几部操作

案例:

	将一个123.txt文件中的内容,读到程序,然后通过程序写出到另一个123_copy.txt文件中,
    文件内容中涉及中文,建议使用字符流
    案例使用:文件字符流
    字符流一般用于处理文本内容 : txt java word .c等文件
import java.io.*;

public class FileIODemo01 {
    public static void main(String[] args){
        //为了在finally实现流的关闭,所以设置为全局变量
        FileReader fileReader=null;
        FileWriter fileWriter=null;
        try {
            //1.创建文件对象路径  注意编码格式,默认新建文件的格式是utf-8
            File file=new File("D:\\123.txt");//源文件
            File descFile=new File("D:\\123_copy.txt");//目标文件
            
            //2.创建流(源文件进行读,目标文件进行写)
            fileReader=new FileReader(file);
            fileWriter=new FileWriter(descFile);
            //FileReader fileReader1=new FileReader("D:\\123.txt");//读取源文件  等价于上面两步
            
            //3.开始数据读写
            /*
                输入流中的方法
                int read();返回读入的一个字符(返回字符对应的码),如果达到文件末尾,返回-1
                输出流中的方法
                void write(int c);向文件中写入一个字符
             */
            //循环读取源文件中的内容,如果没有读到末尾,就将读到内容写到的内容写出到目标文件
//            int data;//用于存储每次读取到的内容
//            while((data=fileReader.read())!=-1){//如果读到内容不等于-1表示没有到文件末尾
//                //向目标文件写入读取的内容
//                    fileWriter.write(data);
//            }
            /*
        int read(char[] chs)返回读入到数组字符的个数,如果达到文件末尾,返回-1 	int代表返回类型
        void write(char[] chs,int off,int length);写入字符数组中chs的一部分,off是从哪个位置开始写,length表示要写多长
         */
            char[] chars=new char[10];//容器,用来装字符
            int length;//用于存储每次读取到数组中的字符的个数
            while ((length=fileReader.read(chars))!=-1) {
                //将字符数组中的内容写出到目标文件
                fileWriter.write(chars,0,length);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.流的关闭
            if (fileReader!=null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileWriter!=null){
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

}

字节流一般用于处理非文本文件(.png .mp3 .mp4 .avi等)

案例:

	复制110.mp4到110_copy.mp4
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class FileIODemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建文件对象
        //创建路径,确定路径是存在的
        File file=new File("D:\\图片和视频\\110.mp4");
        File file1=new File("D:\\图片和视频\\110_copy.mp4");
        //2.创建流
        FileInputStream fileInputStream=new FileInputStream(file);
        FileOutputStream fileOutputStream=new FileOutputStream(file1);
        //3.读写
        /*
        int read;读一个字节返回,若为-1表示读到文件末尾
        void write(int data);写一个字节
         */
        /*
        int read(byte[] bs);返回每次输入到数组中的字节个数如果到了文件末尾则返回-1
        void write(byte[] bs,int off,int length)
            写入字节数组bs的一部分,off表示从哪里开始写length表示写多长
         */
        byte[] bs=new byte[10];
        int length;
        while((length=fileInputStream.read(bs))!=-1){
            fileOutputStream.write(bs,0,length);
        }
        //4.关闭
        fileInputStream.close();
        fileOutputStream.close();
    }
}

在使用文件字节流做复制的时候,速度很慢, 通常建议使用缓冲字节流来实现复制

import java.io.*;
import java.nio.Buffer;

public class BufferedDemo01 {
    public static void main(String[] args) throws Exception {
        //1.创建文件
        File file=new File("D:\\图片和视频\\110.mp4");
        File file1=new File("D:\\图片和视频\\110_copy.mp4");
        //2.创建流(最终使用的是缓冲流)
            //2.1先创建文件流(文件字节流)
            FileInputStream fis=new FileInputStream(file);
            FileOutputStream fos=new FileOutputStream(file1);
            //2.2根据文件流创建缓冲流
        BufferedInputStream bis=new BufferedInputStream(fis);
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //3.读写
        byte[] bs=new byte[1024];
        int length;
        while((length=bis.read(bs))!= -1) {//重复多次,知道写完
            bos.write(bs,0,length);
        }
        //4.关闭流
        //直接关闭外层流
        bos.close();
        bis.close();
    }
}

随机流:
    RandomIOAccessFile类支持随机访问,
        程序可以直接跳到文件的任意地方来进行读或写
        RandomAccessFile对象包含一个记录指针,用于标记当前读写的位置
        RandomAccessFile可以自由的移动记录指针
        关于指针的方法:
        Long getFilePointer();获取文件记录指针的当前位置
        void seek(int pos);将文件记录指针定位到pos位置
        构造器
        public RandomAccessFile(File file,String mode);
            mode参数:该参数指定RandomAccessFile的访问模式
            r:以只读方式打开
            rw:以读写方式打开
            rwd:以读写方式打开,同步文件内容
            rws:以读写方式打开,同步文件内容和元数据更新
                (元数据:描写数据的数据,对数据及信息资源的描述性信息)

操作的文件是事先建好的,里面内容如下图,文件格式为ANSI (ANSI可以深入了解一下)
在这里插入图片描述

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.util.RandomAccess;

public class RandomIODemo01 {
    public static void main(String[] args) throws Exception {
        //写入的文件编码格式为ANSI 文件里面的内容为123456789  插入后的内容为1234056789
        
        //1.创建文件路径
        File file=new File("D:\\test.txt");
        
        //2.创建流
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        
        //3.读写
        
        //3.1移动记录指针到4位置后一位
        raf.seek(4);
        //3.2将4以后的内容存储起来,需要读取文件中的内容,然后将内容拼接;字符串的拼接
        //3.2.1创建StringBuilder对象来存储后续内容
        StringBuilder sb=new StringBuilder();
        //3.2.2读取4以后的文件内容
        byte[] bs=new byte[10];
        int length;
        while((length=raf.read(bs))!=-1){
            //3.2.3将读取到内容转换成字符串拼接到sb中
            String str=new String(bs,0,length);
            sb.append(str);
        }
        //3.3再将指针移到4位置
        raf.seek(4);
        //3.4 将0写入
        raf.write('0');
        //3.5将存储到sb中内容写入到文件中
        //3.5.1先将sb中的内容转为String
        String s=sb.toString();
        //3.5.2再把String转为byte数组
        byte[] s_bs=s.getBytes();
        //3.5.3再把byte数组写入到文件中
        raf.write(s_bs);
        //4.关闭
        raf.close();
    }
}

执行后:
在这里插入图片描述
seek的方法介绍
在这里插入图片描述
一个小案例:

	![在这里插入图片描述](https://img-blog.csdnimg.cn/1b160ce8332b4be2aea6be9514d8f693.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Lq65LiW6Ze055qE54Of54Gr,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
package work.day0309;

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

/**
 *     1.接受用户输入的内容
 *     2.创建文件
 *          2.1指定文件路径
 *          2.2判断
 *     3.创建随机流
 *     4.写入
 *     5.移动指针
 *     6.写入
 *     7.关闭流
 *
 */
public class RandomAccessFileTest {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        File file=null;
        RandomAccessFile raf = null;
        byte[] bs=null;

        //文件路径
//        if (!file.exists())
//            try {
//                //当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
//                file.createNewFile();
//            }catch (IOException e){
//                e.printStackTrace();
//            }
        try {
            file=new File("test.txt");
            if (!file.exists()){//不存在,创建一个
                file.createNewFile();
            }
            raf=new RandomAccessFile(file,"rwd");
            System.out.println("请输入你的姓名:");
            String name=scan.next();
            bs=name.getBytes(StandardCharsets.UTF_8);//设置编码格式
            raf.write(bs);

            System.out.println("请输入你的手机号:");
            String phone=scan.next();
            bs=phone.getBytes(StandardCharsets.UTF_8);
            raf.seek(12);//将指针移到名字后面
            raf.write(bs);
            System.out.println("请输入身份证号:");
            String idNum=scan.next();
            bs=idNum.getBytes(StandardCharsets.UTF_8);
            raf.seek(12+11);//将指针移到名字+手机号后一位
            raf.write(bs);
            System.out.println("请输入你的资费信息:");
            String money=scan.next();
            bs=money.getBytes(StandardCharsets.UTF_8);
            raf.seek(12+11+18);//将指针移到姓名+手机号+身份证后一位
            raf.write(bs);
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            //关流
            try{
                if (raf!=null) {
                    raf.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        scan.close();
    }
}

实现效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值