首页 > 编程语言 >javaseday28 IO

javaseday28 IO

时间:2024-09-22 22:54:07浏览次数:10  
标签:String fos read write IO javaseday28 new public

IO流

IO流;存储和读取数据的解决方案。

纯文本文件:Windows自带的记事本打开能读懂的文件,word和Excel不是纯文本文件,txt和md是纯文本文件。

小结

 IO流体系

FileOutputStream

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //创建对象
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\a.txt");
        //传输数据(字节),根据asicii码为 a
        fos.write(97);
        //关闭资源
        fos.close();
    }
}

a

FileOutputStream细节

 

FileOutputStream写数据的3种方式

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //创建对象
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\a.txt");
        //传输数据(字节),根据asicii码为 a
//        fos.write(97);
        //传输byte数组
        byte[] bytes = {97,98,99,100,101,102};
//        fos.write(bytes);
        fos.write(bytes,1,3);
        /**
         * 参数一:要写入的数组
         * 参数二:写入的起始索引
         * 参数三:写入的个数
         */
        //关闭资源
        fos.close();
    }
}

换行和续写

public class Demo3 {
    public static void main(String[] args) throws IOException {
        /**
         * 不同的操作系统的换行符号不同
         * windos \r\n
         *linux \n
         * mac \r
         */
        /**
         * 续写 在创建FileOutputStream对象时调用不用的构造方法即可
         * FileOutputStream fos = new FileOutputStream("javaseday28Io\\a.txt",true);即为保存数据的续写
         */
        //创建对象
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\a.txt",true);
        //传输数据(字节),根据asicii码为 a
        //换行和续写
        //换行
        String s1 = "duzhelaiyizhengshui";
        byte[] bytes1 = s1.getBytes();
        fos.write(bytes1);
        //将换行符号使用字符串表示并写入

        String s2 = "\r\n";
        byte[] bytes2 = s2.getBytes();
        fos.write(bytes2);
        String s3 = "666";
        byte[] bytes3 = s3.getBytes();
        fos.write(bytes3);

        //关闭资源
        fos.close();
    }
}

FileOutputStream的小结

FileInputStream

public class Demo1 {
    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */
        FileInputStream fos = new FileInputStream("javaseday28Io\\a.txt");
        int r1 = fos.read();
        System.out.println((char) r1);
        int r2 = fos.read();
        System.out.println((char) r2);

        int r3 = fos.read();
        System.out.println((char) r3);

        int r4= fos.read();
        System.out.println((char) r4);

        int r5 = fos.read();
        System.out.println((char) r5);

        int r6 = fos.read();//-1
        System.out.println(r6);

        fos.close();
    }
}

细节

FileInputStream的循环读取

public class Demo2 {
    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */
        FileInputStream fos = new FileInputStream("javaseday28Io\\a.txt");
        int r1;
        while ((r1 = fos.read()) != -1){
            System.out.println((char)r1);
        }


        fos.close();
    }
}

FileInputStream的拷贝文件

public class Demo3 {
    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */
        FileInputStream fis = new FileInputStream("C:\\Users\\20724\\Desktop\\123.jpg");
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\123.jpg");
        int r1;
        //将读取到的信息写入目标文件
        while ((r1 = fis.read()) != -1){
            fos.write(r1);
        }
        //关闭资源
        fos.close();
        fis.close();
    }
}

文件拷贝的弊端和解决方法

文件拷贝单个字符拷贝较慢,可以使用数组进行拷贝。

public class Demo4 {

        public static void main(String[] args) throws IOException {
            /**
             * 如果读取到空值则返回-1
             */


            FileInputStream fis = new FileInputStream("C:\\Users\\20724\\Desktop\\123.jpg");
            FileOutputStream fos = new FileOutputStream("javaseday28Io\\123.jpg");
            //创建一个5MB的数组存储数据
            byte[] bytes = new byte[1024*1024*5];
            //记录每次数组中写入的数据的长度,一遍输出的时候知道输出几个字符
            int len;
            //将读取到的信息写入目标文件
            //将数据读取到数组是是将读取的字符覆盖数组中已有的字符,如果没有被覆盖到就会保留
            while ((len = fis.read(bytes)) != -1){
                //由于没有被覆盖到就会保留,所以向文件写入时要根据读取数据的长度写入
                fos.write(bytes,0,len);
            }
            //关闭资源
            fos.close();
            fis.close();
        }

}

IO流中不同JDK版本捕获异常的方式

基本写法:
public class Demo5 {
    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */

        long start = System.currentTimeMillis();

        //由于代码块中的变量只能在本块中访问,为了在final中关闭流因此定义在外面。
        //定义之后不赋值会出现未初始化错误所以赋值为null
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("C:\\Users\\20724\\Desktop\\123.jpg");
            fos = new FileOutputStream("javaseday28Io\\123.jpg");
            byte[] bytes = new byte[1024*1024*5];
            int len;
            while ((len = fis.read(bytes)) != -1){
                fos.write(bytes,0,len);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            //判断是否为空,即是否成功创建了流对象
            if (fos != null){
                //捕获关闭流时的异常
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            //判断是否为空,即是否成功创建了流对象
            if (fis != null){
                //捕获关闭流时的异常
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            
            }
        }
        long end = System.currentTimeMillis();
        System.out.println((end-start)/1000.0);
    }
}

public class Demo6 {

    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */
        /**
         * JDK7 的写法
         * 不需要关闭流
         */

        try(FileInputStream fis = new FileInputStream("C:\\Users\\20724\\Desktop\\123.jpg");
            FileOutputStream fos = new FileOutputStream("javaseday28Io\\123.jpg")) {
            byte[] bytes = new byte[1024*1024*5];
            int len;
            while ((len = fis.read(bytes)) != -1){
                fos.write(bytes,0,len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
public class Demo7 {
    public static void main(String[] args) throws IOException {
        /**
         * 如果读取到空值则返回-1
         */
        /**
         * JDK9 的写法
         * 不需要关闭流
         */
        FileInputStream fis = new FileInputStream("C:\\Users\\20724\\Desktop\\123.jpg");
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\123.jpg");
        try(fis;fos) {
            byte[] bytes = new byte[1024*1024*5];
            int len;
            while ((len = fis.read(bytes)) != -1){
                fos.write(bytes,0,len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

字符集

ASCII

GBK

小结

Unicode

小结

出现乱码的原因

扩展

java中的编码和解码

public class Demo1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = "hao读者";
        //使用默认编码方法即utf8
        byte[] bytes1 = str.getBytes();
        System.out.println(Arrays.toString(bytes1));
        //[104, 97, 111, -24, -81, -69, -24, -128, -123]
        //使用GBK编码
        byte[] bytes2 = str.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));
        //[104, 97, 111, -74, -63, -43, -33]

        //解码
        String s2 = new  String(bytes1);
        System.out.println(s2);
        //hao读者
        //使用错误的解码方式
        String s3 = new  String(bytes1,"GBK");
        System.out.println(s3);
        //出现乱码 hao璇昏��

        String s4 = new  String(bytes2,"GBK");
        System.out.println(s4);
        //hao读者
    }
}

字符流

FileReader

    public static void main(String[] args) throws IOException {
        /*
            第一步:创建对象
            public FileReader(File file)        创建字符输入流关联本地文件
            public FileReader(String pathname)  创建字符输入流关联本地文件

            第二步:读取数据
            public int read()                   读取数据,读到末尾返回-1
            public int read(char[] buffer)      读取多个数据,读到末尾返回-1

            第三步:释放资源
            public void close()                 释放资源/关流
        */

        //1.创建对象并关联本地文件
        FileReader fr = new FileReader("myio\\a.txt");
        //2.读取数据 read()
        //字符流的底层也是字节流,默认也是一个字节一个字节的读取的。
        //如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节

        //read()细节:
        //1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
        //2.在读取之后,方法的底层还会进行解码并转成十进制。
        //  最终把这个十进制作为返回值
        //  这个十进制的数据也表示在字符集上的数字
        //  英文:文件里面二进制数据 0110 0001
        //          read方法进行读取,解码并转成十进制97
        //  中文:文件里面的二进制数据 11100110 10110001 10001001
        //          read方法进行读取,解码并转成十进制27721

        // 我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了

        int ch;
        while((ch = fr.read()) != -1){
            System.out.print((char)ch);
        }

        //3.释放资源
        fr.close();

    }

带参数的Reader方法

    public static void main(String[] args) throws IOException {
        /*
            第一步:创建对象
            public FileReader(File file)        创建字符输入流关联本地文件
            public FileReader(String pathname)  创建字符输入流关联本地文件

            第二步:读取数据
            public int read()                   读取数据,读到末尾返回-1
            public int read(char[] buffer)      读取多个数据,读到末尾返回-1

            第三步:释放资源
            public void close()                 释放资源/关流
        */


        //1.创建对象
        FileReader fr = new FileReader("myio\\a.txt");
        //2.读取数据
        char[] chars = new char[2];
        int len;
        //read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中
        //空参的read + 强转类型转换
        while((len = fr.read(chars)) != -1){
            //把数组中的数据变成字符串再进行打印
            System.out.print(new String(chars,0,len));
        }
        //3.释放资源
        fr.close();

    }

FileWriter

构造方法

成员方法

书写细节

    public static void main(String[] args) throws IOException {
        //保存文件中的数据
        FileWriter fw = new FileWriter("javaseday28Io\\a.txt",true);

//        fw.write(97);
        String st = "asd哈哈哈";
//        fw.write(st);
//        fw.write(st,2,4);
        char[] chars = {'a','c','b','你','好'};
//        fw.write(chars);
        fw.write(chars,1,4);

        fw.close();
    }

字符流的原理解析

输入流解析

    public static void main(String[] args) throws IOException {

        FileReader fr = new FileReader("myio\\b.txt");
        fr.read();//会把文件中的数据放到缓冲区当中

        //清空文件
        FileWriter fw = new FileWriter("myio\\b.txt");

        //请问,如果我再次使用fr进行读取
        //会读取到数据吗?

        //会把缓冲区中的数据全部读取完毕

        //正确答案:
        //但是只能读取缓冲区中的数据,文件中剩余的数据无法再次读取
        int ch;
        while((ch = fr.read()) != -1){
            System.out.println((char)ch);
        }


        fw.close();
        fr.close();


    }
输出流解析

flush和close方法

    public static void main(String[] args) throws IOException {


        FileWriter fw = new FileWriter("myio\\a.txt");


       fw.write("我的同学各个都很厉害");
       fw.write("说话声音很好听");

       fw.flush();

       fw.write("都是人才");
       fw.write("超爱这里哟");

      fw.close();

       fw.write("B站");

    }

使用场景

综合练习

练习一:拷贝

public class Test {
    public static void main(String[] args) throws IOException {
        /**
         * 拷贝文件
         */
        //目标文件夹
        File f1 = new File("C:\\Users\\20724\\Desktop\\FileTest");
        File f2= new File("C:\\Users\\20724\\Desktop\\123");
        copyfile(f1,f2);
    }

    //复制方法
    private static void copyfile(File f1, File f2) throws IOException {
        //创建文件夹防止无法存放文件
        f2.mkdir();
        //使用递归的方法
        //遍历数组
        //判断
        File[] files = f1.listFiles();

        for (File file : files) {
            if (file.isFile()){
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(f2,file.getName()));

                int len;
                byte[] bytes = new byte[1024];
                while ((len = fis.read(bytes)) != -1){
                    fos.write(bytes,0,len);
                }

                fos.close();
                fis.close();

            }else {
                //为文件夹进行递归
                copyfile(file,new File(f2,file.getName()));
            }
        }
    }
}

练习二:文件加密

public class Test {
    public static void main(String[] args) throws IOException {
        //文件加密,解密都可以使用只需要修改输入文件和输出文件
        FileInputStream fis = new FileInputStream("javaseday28Io\\cnpy.jpg");
        FileOutputStream fos = new FileOutputStream("javaseday28Io\\678.jpg");

        int len;

        while (( len = fis.read()) != -1){
            fos.write(len ^ 1920);
        }

        fos.close();
        fis.close();
    }
}

练习三:修改文件数据

方法一:
public class Test1 {
    public static void main(String[] args) throws IOException {
        //普通方法写

        //获取文件,读取数据
        FileReader fr = new FileReader("javaseday28Io\\a.txt");
        //接受数据
        StringBuilder sb = new StringBuilder();
        int len;
        while ((len = fr.read()) != -1){
            sb.append((char)len);
        }
        fr.close();
        String string = sb.toString();
        System.out.println();

        //修改数据
        //读去数据
        ArrayList<Integer> list = new ArrayList<>();
        String[] split = string.split("-");
        for (String s : split) {
            list.add(Integer.parseInt(s));
        }

        //修改数据
        Collections.sort(list);

        //写入数据
        //获取写入文件的地址
        FileWriter fw = new FileWriter("javaseday28Io\\b.txt");
        for (int i = 0; i < list.size(); i++) {
            if (i!=list.size()-1){
                fw.write(list.get(i)+"");
                fw.write("-");
            }else {
                fw.write(list.get(i)+"");
            }
        }
        fw.close();
    }
}
方法二:
public class Test2 {
    public static void main(String[] args) throws IOException {
        //普通方法写

        //获取文件,读取数据
        FileReader fr = new FileReader("javaseday28Io\\a.txt");
        //接受数据
        StringBuilder sb = new StringBuilder();
        int len;
        while ((len = fr.read()) != -1){
            sb.append((char)len);
        }
        fr.close();

        //修改数据
        //读去数据
            //使用Stream流进行操作
        Integer[] array = Arrays.stream(sb.toString().split("-"))
                //.map(new Function<String, Integer>() {
                //                    @Override
                //                    public Integer apply(String s) {
                //                        return Integer.parseInt(s);
                //                    }
                //                })
                //将String类型转换为Int类型,Map进行类型转换
                .map(Integer::parseInt)
                .sorted()
                .toArray(Integer[]::new);


        //写入数据
        //获取写入文件的地址
        FileWriter fw = new FileWriter("javaseday28Io\\b.txt");
        //将 , 的间隔符装换位 - 的间隔符
        String s = Arrays.toString(array).replace(", ","-");
        //将头尾的中括号剪裁掉
        String res = s.substring(1, s.length() - 1);
        fw.write(res);
        fw.close();
    }
}

标签:String,fos,read,write,IO,javaseday28,new,public
From: https://blog.csdn.net/m0_72625929/article/details/142351266

相关文章

  • CentOS7使用yum时File contains no section headers. file: file:///etc/yum.repos.d/
    CentOS7使用yum时Filecontainsnosectionheaders.file:file:///etc/yum.repos.d/CentOS-Base.repo,line:1'--2024-09-2221:08:17--http://mirrors.aliyun.com/repo/Centos-7.repo\n'安装好CenOS7后,自带的yum不能直接使用,使用会出现如下问题:原因是没有配置yum源,修改/e......
  • vscode使用continue插件连接LM studio的模型
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、步骤1.LMstudio加载模型2.启动api服务3.修改continue配置文件4.测试二、总结一、步骤1.LMstudio加载模型根据需求设置系统提示词,根据设备显卡和模型大小设置上下文长度和n_gpu_la......
  • [CVPR2024]DeiT-LT Distillation Strikes Back for Vision Transformer Training on L
    在长尾数据集上,本文引入强增强(文中也称为OOD)实现对DeiT的知识蒸馏的改进,实现尾部类分类性能的提升。动机ViT相较于CNN缺少归纳偏置,如局部性(一个像素与周围的区域关系更紧密)、平移不变性(图像的主体在图像的任意位置都应该一样重要)。因此需要大型数据集进行预训练。长尾数据学习......
  • 深入探讨Hailuo AI:基于MoE、Dense和Diffusion模型的AI视频生成技术解析
    1.什么是HailuoAI?近年来,AI生成技术在视频制作领域迅速崛起。众多创新工具使得视频生成变得更加自动化和高效,而HailuoAI正是在这一背景下成为一款备受瞩目的工具。作为MiniMax开发的AI视频生成平台,HailuoAI运用了先进的**MixtureofExperts(MoE)**模型,为用户提供了高......
  • Metric3D v2: A Versatile Monocular Geometric Foundation Model for Zero-shot Metr
    paperMetric3Dv2:AVersatileMonocularGeometricFoundationModelforZero-shotMetricDepthandSurfaceNormalEstimation作者MuHu1∗,WeiYin2∗†,ChiZhang3,ZhipengCai4,XiaoxiaoLong5‡,HaoChen6,KaixuanWang1,GangYu7,ChunhuaShen......
  • 探索 Kubernetes 服务网格:Istio 实战指南
    ......
  • WPF Unable to cast object of type 'System.Windows.Controls.SelectedItemCollectio
    SelectedItemsconverttoIListasbelowfailed;IList<Book>collection2=(IList<Book>)obj; System.InvalidCastExceptionHResult=0x80004002Message=Unabletocastobjectoftype'System.Windows.Controls.SelectedItemCollection'......
  • 从代码到部署:GitHub Actions实现Java项目CI/CD的完整实践
    从代码到部署:GitHubActions实现Java项目CI/CD的完整实践在现代软件开发中,持续集成和持续部署(CI/CD)已经成为了团队高效交付代码的关键策略。通过GitHubActions,可以轻松配置CI/CD流水线,实现从代码提交到部署的自动化工作流。本文将基于英语听力网站(studytool.site)项目介......
  • How to get the exact duration of an audio file in js All In One
    HowtogettheexactdurationofanaudiofileinjsAllInOneerrorsaudiodurationtimeprecisebugtime误差bug❌Reducedtimeprecision/时间精度降低Toofferprotectionagainsttimingattacksandfingerprinting,theprecisionofvideo.currentTim......
  • 【iOS】KVC
    文章目录KVC的定义容器类中KVC的实现KVC设值KVC取值KVC使用KeyPathKVC处理异常KVC处理设值nil异常KVC处理UndefinedKey异常KVC处理数值和结构体类型属性KVC键值验证KVC处理集合简单集合运算符对象运算符KVC处理字典KVC应用动态地取值和设值用KVC来访问和修改......