java案例(Java实战)

 2025-08-11 01:54:01  阅读 233  评论 0

摘要:一、前言今天给大家分享一个自己写的ava实战的小案例,主要功能是实现指定一个文件夹,然后分组压缩里面的文件。其实这个案例还是有一定用途的,比如日志文件夹里面有几千个文件,如果我需要给每个压缩包指定10M,把整个文件夹里面的日志文件都进行压缩,这个案例就能够用得上

一、前言

今天给大家分享一个自己写的ava实战的小案例,主要功能是实现指定一个文件夹,然后分组压缩里面的文件。其实这个案例还是有一定用途的,比如日志文件夹里面有几千个文件,如果我需要给每个压缩包指定10M,把整个文件夹里面的日志文件都进行压缩,这个案例就能够用得上了。废话少说,直接上代码。我这边采用的是最基本的控制台程序,主要还是代码的逻辑有一定的借鉴意义。说明:暂时未考虑文件夹里面还有文件夹的情况。

二、代码示例

新建FileModel.java 实体

主要指定文件名以及文件大小,方便分组的时候使用。

public class FileModel {
    public FileModel(String name, double fileSize) {
        this.name = name;
        this.fileSize = fileSize;
    }

    // 文件名
    public String name;
    // 文件大小KB
    public double fileSize;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getFileSize() {
        return fileSize;
    }

    public void setFileSize(double fileSize) {
        this.fileSize = fileSize;
    }
}

Main.java 代码:

文件夹中文件分组大小采用了递归的方式。为了实现效果代码都放在了Main.java里面。具体代码都有注释,直接看注释就行。

 private static final double FILE_SIZE=5500; // 指定分组压缩的大小 550KB
    private static final String PATH="D:\Test; // 指定要处理的文件夹
    public static void main(String[] args) {
        List list = getFiles(PATH);
        HashMap> map = new HashMap<>();
        getArr(list,FILE_SIZE,map);
        if(map.size()>0)
        {
            for (Double aDouble : map.keySet()) {
                List fileModels = map.get(aDouble);
                batchZipFiles(fileModels,PATH+"\"+aDouble.toString()+".zip");
            }
        }
        System.out.println(map);
    }

    // 递归方式实现文件分组
    private static void getArr(List list, double fileSize,Map> map) {
        List listAdd = new ArrayList<>();
        if (list.size() > 0) {
            for (FileModel fileModel : list) {
                if (listAdd.size() == 0) {
                    listAdd.add(fileModel);
                } else {

                    if (listAdd.stream().mapToDouble(FileModel::getFileSize).sum() < fileSize) {
                        listAdd.add(fileModel);
                        if(listAdd.size()==list.size())
                        {
                            map.put(listAdd.stream().mapToDouble(FileModel::getFileSize).sum(), listAdd);
                        }
                    } else {
                        // 取差集
                        list = list.stream().filter(item -> !listAdd.contains(item)).collect(Collectors.toList());
                        map.put(listAdd.stream().mapToDouble(FileModel::getFileSize).sum(), listAdd);
                        getArr(list,fileSize,map);
                        break;

                    }
                }
            }
        }

    }

    //读取文件夹获取里面文件的名字尺寸 不考虑嵌套文件夹
    private static List getFiles(String path) {
        List files = new ArrayList();
        File file = new File(path);
        File[] tempList = file.listFiles();
        if (tempList != null && tempList.length > 0) {
            for (File value : tempList) {
                if (value.isFile()) {
                    // System.out.println(value.getName() + ":" + getFileSizeString(value.length()));
                    files.add(new FileModel(
                            value.getName(), getFileSizeKB(value.length())
                    ));
                }
            }
        }
        return files;
    }

    // 获取文件大小KB
    private static double getFileSizeKB(Long size) {
        double length = Double.parseDouble(String.valueOf(size));
        return  length / 1024.0;

    }

    // 返回文件大小尺寸
    private static String getFileSizeString(Long size) {
        double length = Double.parseDouble(String.valueOf(size));
        //如果字节数少于1024,则直接以B为单位,否则先除于1024,后3位因太少无意义
        if (length < 1024) {
            return length + "B";
        } else {
            length = length / 1024.0;
        }
        //如果原字节数除于1024之后,少于1024,则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (length < 1024) {
            return Math.round(length * 100) / 100.0 + "KB";
        } else {
            length = length / 1024.0;
        }
        if (length < 1024) {
            //因为如果以MB为单位的话,要保留最后1位小数,
            //因此,把此数乘以100之后再取余
            return Math.round(length * 100) / 100.0 + "MB";
        } else {
            //否则如果要以GB为单位的,先除于1024再作同样的处理
            return Math.round(length / 1024 * 100) / 100.0 + "GB";
        }
    }

    /**
     *  压缩指定文件夹中的所有文件,生成指定名称的zip压缩包
     *
     * @param list 需要压缩的文件名称列表(包含相对路径)
     * @param zipOutPath 压缩后的文件名称
     **/
    public static void batchZipFiles(List list, String zipOutPath) {
        ZipOutputStream zipOutputStream = null;
        WritableByteChannel writableByteChannel = null;
        MappedByteBuffer mappedByteBuffer = null;
        try {
            zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOutPath));
            writableByteChannel = Channels.newChannel(zipOutputStream);

            File file = new File(PATH);
            File[] tempList = file.listFiles();
            List fileList = list.stream().map(FileModel::getName).collect(Collectors.toList());
            File[] addList=new File[fileList.size()];
            assert tempList != null;
            for (File file1 : tempList) {
                if(fileList.contains(file1.getName()))
                {
                    long fileSize = file1.length();
                    //利用putNextEntry来把文件写入
                    zipOutputStream.putNextEntry(new ZipEntry(file1.getName()));
                    long read = Integer.MAX_VALUE;
                    int count = (int) Math.ceil((double) fileSize / read);
                    long pre = 0;
                    //由于一次映射的文件大小不能超过2GB,所以分次映射
                    for (int i = 0; i < count; i++) {
                        if (fileSize - pre < Integer.MAX_VALUE) {
                            read = fileSize - pre;
                        }
                        mappedByteBuffer = new RandomAccessFile(file1, "r").getChannel()
                                .map(FileChannel.MapMode.READ_ONLY, pre, read);
                        writableByteChannel.write(mappedByteBuffer);
                        pre += read;
                    }
                }
            }
            assert mappedByteBuffer != null;
            mappedByteBuffer.clear();
        } catch (Exception e) {

        } finally {
            try {
                if (null != zipOutputStream) {
                    zipOutputStream.close();
                }
                if (null != writableByteChannel) {
                    writableByteChannel.close();
                }
                if (null != mappedByteBuffer) {
                    mappedByteBuffer.clear();
                }
            } catch (Exception e) {

            }
        }
    }

三、展示效果

最终运行效果如下

版权声明:我们致力于保护作者版权,注重分享,被刊用文章【java案例(Java实战)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;

原文链接:https://www.yxiso.com/zhishi/2060529.html

标签:java案例

发表评论:

关于我们
院校搜的目标不仅是为用户提供数据和信息,更是成为每一位学子梦想实现的桥梁。我们相信,通过准确的信息与专业的指导,每一位学子都能找到属于自己的教育之路,迈向成功的未来。助力每一个梦想,实现更美好的未来!
联系方式
电话:
地址:广东省中山市
Email:beimuxi@protonmail.com

Copyright © 2022 院校搜 Inc. 保留所有权利。 Powered by BEIMUCMS 3.0.3

页面耗时0.0345秒, 内存占用1.93 MB, 访问数据库24次

陕ICP备14005772号-15