IO流练习

实现文件切割器

该方法用于将指定文件 original 切割为体积不超过 size 字节的 N 份后, 依次序 放入到 directory 目录中。

其中:

  • 参数 original 表示被拆分的原始文件
  • 参数 size 表示拆分后的文件的体积上限
  • 参数 directory 表示拆分后的文件的存储目录

代码实现

    public int split(final File original, final long size, final File directory) throws IOException {
        // 合法校验
        if (original != null && !original.isFile()) {
            throw new IllegalArgumentException("原始文件不合法");
        }
        if (directory != null && !directory.isDirectory()) {
            throw new IllegalArgumentException("目标目录不合法");
        }
        if (!directory.getParentFile().exists()) {
            directory.getParentFile().mkdirs();
        }

        int n = 0; // 表示拆分后文件个数的变量
        try (FileInputStream fileInputStream = new FileInputStream(original)) {
            if (size < Integer.MAX_VALUE - 8) {
                byte[] bytes = new byte[(int) size];  // 判断如果传入值大于int最大值,按照int最大值存,要预留一部分空间
                int index;
                while ((index = fileInputStream.read(bytes)) != -1) {  // 按照最大值读文件
                    File file = new File(directory, System.nanoTime() + ".temp");  // 每部分文件名
                    try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                        fileOutputStream.write(bytes, 0, index);  // 将读的文件写在指定地点
                        n++;
                    } catch (IOException e) {
                        throw new RuntimeException("写文件错误", e);
                    }
                }
            } else {
                byte[] bytes = new byte[Integer.MAX_VALUE - 8];
                while (fileInputStream.available() > 0) {
                    File outFile = new File(original, System.nanoTime() + ".temp");
                    try (FileOutputStream fileOutputStream = new FileOutputStream(outFile)) {
                        long sum = size;  // 单个文件剩余大小
                        while (sum > Integer.MAX_VALUE - 8 && fileInputStream.available() > 0) {
                            int read = fileInputStream.read(bytes);
                            fileOutputStream.write(bytes, 0, read);
                            sum -= read;
                        }

                        // 处理没有满足单文件大小, 还有内容没读取
                        if (fileInputStream.available() != 0) {
                            int read = fileInputStream.read(bytes);
                            fileOutputStream.write(bytes, 0, read);
                        }
                        n++;
                    } catch (IOException e) {
                        throw new RuntimeException("写文件错误", e);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("读文件错误", e);
        }
        return n; // 返回拆分后的文件个数
    }

实现文件合并器

该方法用于将指定目录 dir 中的多个文件片段依次序合并到同一个文件 target 中,并返
回合并后的文件体积。

其中:

  • 参数 dir 表示文件片段所在的目录
    • 对应将大文件拆分后所得到的N个小文件的存放目录
  • 参数 target 表示合并后的文件的存放路径名

代码实现

	public long join(final File dir, final File target) throws IOException {
        // 合法校验
        if (dir != null && !dir.isDirectory()) {
            throw new IllegalArgumentException("目录不合法");
        }
        if (target != null && !target.isDirectory()) {
            throw new IllegalArgumentException("目标文件不合法");
        }
        // 保证存储的文件夹存在
        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }

        try (FileOutputStream fileOutputStream = new FileOutputStream(target)) {
            File[] files = dir.listFiles((d, name) -> name.endsWith(".temp"));
            assert files != null;
            for (File file : files) {
                try (FileInputStream fileInputStream = new FileInputStream(file)) {
                    byte[] bytes = new byte[8192]; // 缓冲区大小为 8KB
                    int read;
                    while ((read = fileInputStream.read(bytes)) != -1) {
                        fileOutputStream.write(bytes, 0, read);
                    }
                } catch (IOException e) {
                    throw new IOException("写错误", e);
                }
            }
        } catch (IOException e) {
            throw new IOException("写文件错误", e);
        }
        return target.length(); // 返回合并后的文件大小
    }

你可能感兴趣的:(Java,java)