IO流练习

练习1:拷贝文件夹

分析:自己写的有点混乱,思路也不对。

public class IO5 {
    public static void main(String[] args) throws IOException {
        //拷贝文件夹
        //首先先有这样一个文件夹
        File file = new File("src/com/liu");
        copy(file);
    }

    private static void copy(File file) throws IOException {
        //新文件夹
        // 1. 先获取文件夹的名字
        String path = "aaa/" + file.getName();
        // 2. 创建文件夹要存储的路径File对象
        File dir = new File(path);
        // 3. 创建文件夹
        dir.mkdirs();
        //原来文件夹下的所有内容
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                copy(f);
            } else {
                // 为文件创建一个读取流
                FileInputStream fis = new FileInputStream(f);
                int b;
                while ((b = fis.read()) != -1) {
                    File destionation = new File(path + "/" + f.getName());
                    destionation.createNewFile();
                    FileOutputStream fos = new FileOutputStream(destionation);
                    fos.write(b);
                }
            }
        }
    }
}

修改:将此文件夹拷贝到哪个目录下,所以有两个路径,分别是表示此文件夹的from和到哪个目录下to 。

然后如何拷贝呢?

首先要把新的目标文件夹创建出来:获取此文件夹的名字,然后创建到to目录下。

然后把文件夹下的所有内容都拷贝到新的目标文件夹下

如果是文件,则路径是:new File(newDir, f.getName()),这里我刚开始是使用+进行拼接的,其实这样不对,应该是使用File的2个参数的构造方法。 

而如果是文件夹,则递归调用此方法,但需要注意路径的传递:copy(f, newDir)。

public class IO6 {
    public static void main(String[] args) throws IOException {
        File from = new File("src/com/liu");
        File to = new File("bbb");
        copy(from, to);
    }

    private static void copy(File from, File to) throws IOException {
        // 创建新的目标文件夹
        File newDir = new File(to, from.getName());
        newDir.mkdirs(); 

        // 处理原文件夹下的所有内容
        File[] files = from.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                copy(f, newDir);  // 递归处理子文件夹
            } else {
                // 为文件创建读取流和写入流
                FileInputStream fis = new FileInputStream(f);
                FileOutputStream fos = new FileOutputStream(new File(newDir, f.getName()));

                // 使用缓冲区提高效率
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    fos.write(buffer, 0, length);
                }

                // 关闭流
                fos.close();
                fis.close();
            }
        }
    }
}

练习2: 加密和解密文件

为了保证文件的安全性,就需要对原始文件进行加密存储,再使用的时候再对其进行解密处理。
加密原理:对原始文件中的每一个字节数据进行更改,然后将更改以后的数据存储到新的文件中,
解密原理:读取加密之后的文件,按照加密的规则反向操作,变成原始文件。

这里需要介绍一个知识点就是:一个二进制数①与另外一个二进制数②进行异或得到一个值,当这个值再与②进行异或的话,就能得到原来的二进制①。

所以可以利用这个进行加密和解密。

加密的实现: 

public class IO7 {
    public static void main(String[] args) throws IOException {
        // 要读取的文件肯定是要存在的
        FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\image-20240722173741395.png");
        // 要写入到哪里
        FileOutputStream fos = new FileOutputStream("111.jpg");
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b ^ 10);
        }
        fos.close();
        fis.close();
    }
}

解密的实现:

public class IO8 {
    public static void main(String[] args) throws IOException {
        // 要读取的文件
        FileInputStream fis = new FileInputStream("111.jpg");
        // 要写入到哪里
        FileOutputStream fos = new FileOutputStream("222.png");
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b ^ 10);
        }
        fos.close();
        fis.close();
    }
}

练习3: 修改文件中的数据

文本文件中有以下的数据:2-1-9-4-7-8
将文件中的数据进行排序,变成以下的数据:1-2-4-7-8-9

分析:1、首先将文件中的所有数据读取出来,放到StringBuilder中再转换为字符串。

2、提取其中的数字,由于是字符串,所以使用parseInt()方法将字符串转换为整数。

集合中有一个工具类Collections,里面有一个sort方法可以对整数升序排列。

3、如何再把整数写进去呢?

由于集合中存的是整数,把整数一个一个地和空字符串“”进行拼接转换为字符串①,然后再利用write方法逐个写入。

这里我是使用字节输出流的write(int b)方法,需要①调用getBytes()方法转换为字节。

其实还可以使用字符输出流,可以直接写入字符串①,就不需要再getBytes()方法转换为字节了。

public class IO9 {
    public static void main(String[] args) throws IOException {
        // 首选读取文件
        FileInputStream fis = new FileInputStream("a.txt");
        int b;
        StringBuilder sb = new StringBuilder();
        while ((b = fis.read()) != -1) {
            sb.append((char)b);
        }
        // 把其中的整数提取出来并排序
        String s = sb.toString();
        String[] ss = s.split("-");
        ArrayList<Integer> list = new ArrayList<>();
        for (String s1 : ss) {
            list.add(Integer.parseInt(s1));
        }
        Collections.sort(list);
        System.out.println(list);
        // 写到新文本中
        FileOutputStream fos = new FileOutputStream("b.txt");
        int len = list.size();
        for (int i = 0; i < len; i++) {
            if (i == len -1) {
                fos.write((list.get(i) + "").getBytes());
            } else {
                fos.write((list.get(i) + "").getBytes());
                fos.write("-".getBytes());
            }
        }
    }
}

修改:

还有另外一种方式的实现,可以对第2步和第3步改进。

第2步还可以使用Stream流。

这里我是使用collect()方法将结果收集到List中了。然后还是使用Collections里的sort方法对集合中的整数升序排列。

        // 还可以使用Stream流把其中的整数提取出来并排序
        String s = sb.toString();
        String[] ss = s.split("-");
        List<Integer> list = Arrays.stream(ss)
                .map(Integer::parseInt)
                .collect(Collectors.toList());
        Collections.sort(list);

在Java中,Stream中的sorted方法可以对流中的数据进行排列,toArray方法可以将流中的元素收集到一个数组中。 

        Integer[] list = Arrays.stream(ss)
                .map(Integer::parseInt)
                .sorted()
                .toArray(Integer[]::new);

第3步其实可以利用toString方法将集合整个转换为字符串,直接一下全部写入,不用再一个一个写入了。

        String str = list.toString().replace(", ", "-");
        String substr = str.substring(1, str.length() - 1);
        FileWriter fw = new FileWriter("b.txt");
        fw.write(substr);
        fw.close();

在使用IDEA的快捷键提示功能时,要注意提示的变量是否正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值