最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java實現(xiàn)文件大小過濾功能(附源碼)

 更新時間:2025年06月27日 09:19:38   作者:Katie。  
在實際開發(fā)中,經(jīng)常需要對大量文件進行批量處理,對于這些場景,開發(fā)者往往需要根據(jù)文件的大小進行篩選,本文就來利用Java實現(xiàn)文件大小過濾功能,有需要的可以了解下

一、項目背景詳細介紹

在實際開發(fā)中,經(jīng)常需要對大量文件進行批量處理,如日志清理、備份管理、數(shù)據(jù)遷移等。對于這些場景,開發(fā)者往往需要根據(jù)文件的大小進行篩選:將超過指定閾值的大文件單獨歸檔,或者將過小的臨時文件刪除,以節(jié)省存儲空間、提升系統(tǒng)性能或增強數(shù)據(jù)安全性。

  • 日志管理:服務器產(chǎn)生大量日志文件,某些日志可能因為異常拼接或循環(huán)寫入而過大,需要及時過濾并歸檔,否則會導致磁盤被快速占滿。
  • 備份清理:定期對歷史備份文件執(zhí)行大小篩選,將超過一定大小的全量備份分批上傳至云存儲,將小文件留在本地以便快速恢復。
  • 數(shù)據(jù)遷移:遷移時只處理小于某個大小的文件,以保證網(wǎng)絡帶寬與時間窗口可控;對大文件則分片或異步上傳。
  • 安全掃描:靜態(tài)資源或可執(zhí)行文件大小異??赡芤馕吨鴥?nèi)容被篡改或注入,通過大小過濾可初步發(fā)現(xiàn)異常文件。

因此,實現(xiàn)一個“Java 文件大小過濾”工具,能夠靈活地根據(jù)用戶指定的大小閾值,對目錄或文件列表進行掃描、篩選與分類,具有重要的實用價值。

二、項目需求詳細介紹

本項目的目標是設計并實現(xiàn)一個通用的 Java 文件大小過濾模塊,主要需求包括:

1.閾值條件

  • 支持“最小大小閾值”和“最大大小閾值”兩種過濾模式,用戶可單獨指定或同時指定。
  • 閾值單位支持字節(jié)(B)、千字節(jié)(KB)、兆字節(jié)(MB)、千兆字節(jié)(GB),并提供自動換算。

2.掃描范圍

  • 支持對單個文件進行判斷,輸出是否符合條件。
  • 支持對指定目錄進行遞歸掃描,返回滿足條件的文件列表及其大小信息。
  • 支持對多條路徑(文件或目錄)進行批量處理。

3.輸出格式

  • 提供簡單的 List<File> 返回,也可定制輸出為 Map<File, Long>(文件-大小映射)。
  • 命令行工具模式下,打印文件路徑與大小,并可按大小升序或降序排序。
  • 支持將結(jié)果導出為 CSV、JSON 或純文本格式,便于后續(xù)集成。

4.性能與并發(fā)

  • 對大目錄進行掃描時,采用多線程并行遍歷與判斷,以提升處理速度。
  • 支持線程池配置、最大并發(fā)數(shù)限制,避免過度占用 CPU 或 I/O。

5.易用性與擴展

對外提供靜態(tài)工具類 FileSizeFilter,方法簽名示例:

public static List<File> filterBySize(File directory, long minBytes, long maxBytes);

支持命令行執(zhí)行 java -jar filesizefilter.jar --min 10MB --max 1GB --path /data/logs。

后續(xù)可擴展結(jié)合日期、文件類型、名稱模式等更多過濾條件。

6.異常與日志

  • 針對無效路徑、文件權限不足等情況進行友好異常提示。
  • 掃描過程中對錯誤文件記錄日志,并可選擇忽略或中斷操作。

三、相關技術詳細介紹

為滿足以上需求,將涉及并運用以下核心技術與類庫:

1.Java 文件 I/O 與 NIO

  • java.io.File:舊式文件與目錄操作。
  • java.nio.file.Filesjava.nio.file.Path:新 I/O API,支持流式遍歷與更高效的文件屬性讀取。
  • java.nio.file.attribute.BasicFileAttributes:獲取文件大小、最后修改時間等元數(shù)據(jù)。

2.并發(fā)與線程池

  • java.util.concurrent.ExecutorService、ForkJoinPool:管理并發(fā)任務,支持目錄遞歸掃描時的分支并行。
  • CompletableFuture:實現(xiàn)異步鏈式處理與結(jié)果合并。

3.命令行解析

  • 可選 Apache Commons CLI、Picocli、JCommander 等庫,簡化參數(shù)定義與幫助信息展示。
  • 解析大小閾值字符串(如“10MB”)并轉(zhuǎn)換為字節(jié)值。

4.序列化與導出

  • Jackson 或 Gson:將結(jié)果序列化為 JSON。
  • 使用 StringBuilderPrintWriter 導出為純文本或 CSV 格式。

5.日志框架

SLF4J + Logback:記錄掃描進度、錯誤文件及異常堆棧,支持日志級別控制。

6.單元測試

  • JUnit 5:編寫測試用例,覆蓋各種邊界情況,如空目錄、權限受限文件、閾值邊界值等。
  • Mockito:模擬文件系統(tǒng)或依賴,以便在測試中控制文件屬性。

四、實現(xiàn)思路詳細介紹

結(jié)合需求與技術,項目的實現(xiàn)思路可以分為以下幾個步驟:

1.閾值解析

  • 編寫 SizeParser 工具,將用戶傳入的字符串(如“1.5GB”、“1024KB”、“500”)解析為對應的字節(jié)數(shù)(long)。
  • 支持大小寫單位、整數(shù)和小數(shù)格式。

2.文件掃描

  • 對于單個文件:直接調(diào)用 Files.size(Path) 讀取大小,并與閾值比較。
  • 對于目錄遞歸:使用 Files.walk(Path start, FileVisitOption…)ForkJoinPool 結(jié)合 RecursiveTask 進行并行遍歷。

3.并發(fā)執(zhí)行

  • 在目錄遍歷過程中,將子目錄掃描任務提交到線程池或 ForkJoin 框架,以提高 I/O 并行度。
  • 收集所有符合條件的文件,使用線程安全的集合(如 ConcurrentLinkedQueue)存儲中間結(jié)果。

4.結(jié)果排序與導出

  • 在掃描完成后,對結(jié)果列表按文件大小進行升序或降序排序。
  • 根據(jù)用戶指定的導出格式,調(diào)用不同序列化或?qū)懗鲞壿嫛?/li>

5.命令行入口

  • Main 類中使用 CLI 庫解析參數(shù)(最小/最大大小、路徑列表、輸出格式、并發(fā)數(shù)等)。
  • 調(diào)用工具類方法,獲取結(jié)果并在控制臺打印或?qū)С鑫募?/li>

6.錯誤處理與日志

  • 針對 IOException、無權限訪問等異常,記錄日志并在測試模式下拋出或在生產(chǎn)模式下忽略。
  • 提供 “--fail-on-error” 選項,決定遇到錯誤時是否中斷掃描。

五、完整實現(xiàn)代碼

// ============================================================================
// 文件:SizeParser.java
// 包名:com.example.filesizefilter
// 功能:將用戶輸入的大小閾值字符串(如 "1.5GB"、"1024KB")解析為字節(jié)數(shù)
// ============================================================================
package com.example.filesizefilter;

import java.util.regex.*;
import com.example.filesizefilter.exception.FilterException;

public class SizeParser {
    // 支持單位:B、KB、MB、GB(大小寫均可)
    private static final Pattern PATTERN = Pattern.compile(
        "\\s*([0-9]+(?:\\.[0-9]+)?)\\s*(B|KB|MB|GB)?\\s*", Pattern.CASE_INSENSITIVE);

    /**
     * 將字符串表示的大小轉(zhuǎn)換為字節(jié)數(shù)
     * @param sizeStr 大小字符串,如 "512MB", "1.5 GB", "1024"
     * @return 對應的字節(jié)數(shù)
     */
    public static long parse(String sizeStr) {
        Matcher m = PATTERN.matcher(sizeStr);
        if (!m.matches()) {
            throw new FilterException("無法解析大小閾值:" + sizeStr);
        }
        double value = Double.parseDouble(m.group(1));
        String unit = m.group(2);
        if (unit == null || unit.equalsIgnoreCase("B")) {
            return (long) value;
        } else if (unit.equalsIgnoreCase("KB")) {
            return (long) (value * 1024L);
        } else if (unit.equalsIgnoreCase("MB")) {
            return (long) (value * 1024L * 1024L);
        } else if (unit.equalsIgnoreCase("GB")) {
            return (long) (value * 1024L * 1024L * 1024L);
        } else {
            throw new FilterException("不支持的單位:" + unit);
        }
    }
}

// ============================================================================
// 文件:FilterResult.java
// 包名:com.example.filesizefilter
// 功能:封裝過濾后文件及其大小信息
// ============================================================================
package com.example.filesizefilter;

import java.io.File;

public class FilterResult {
    private final File file;
    private final long size;

    public FilterResult(File file, long size) {
        this.file = file;
        this.size = size;
    }
    public File getFile() { return file; }
    public long getSize() { return size; }
}

// ============================================================================
// 文件:FileSizeFilter.java
// 包名:com.example.filesizefilter
// 功能:核心過濾類,支持按最小、最大閾值對文件或目錄遞歸掃描并行過濾
// ============================================================================
package com.example.filesizefilter;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.*;
import com.example.filesizefilter.exception.FilterException;

public class FileSizeFilter {
    /**
     * 按閾值過濾單個文件
     * @param file      文件對象
     * @param minBytes  最小字節(jié)數(shù)(null 表示不限制)
     * @param maxBytes  最大字節(jié)數(shù)(null 表示不限制)
     * @return 如果符合條件返回 FilterResult,否則返回 null
     */
    public static FilterResult filter(File file, Long minBytes, Long maxBytes) {
        if (!file.isFile()) {
            throw new FilterException("不是文件:" + file.getPath());
        }
        long size = file.length();
        if ((minBytes == null || size >= minBytes) && (maxBytes == null || size <= maxBytes)) {
            return new FilterResult(file, size);
        }
        return null;
    }

    /**
     * 遞歸掃描目錄并按大小過濾,單線程實現(xiàn)
     */
    public static List<FilterResult> filterDirectory(File dir, Long minBytes, Long maxBytes) {
        if (!dir.isDirectory()) {
            throw new FilterException("不是目錄:" + dir.getPath());
        }
        List<FilterResult> results = new ArrayList<>();
        try {
            Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
                    long size = attrs.size();
                    if ((minBytes == null || size >= minBytes) && (maxBytes == null || size <= maxBytes)) {
                        results.add(new FilterResult(path.toFile(), size));
                    }
                    return FileVisitResult.CONTINUE;
                }
                @Override
                public FileVisitResult visitFileFailed(Path path, IOException exc) {
                    // 記錄日志并繼續(xù)
                    System.err.println("無法訪問文件:" + path + ",原因:" + exc.getMessage());
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            throw new FilterException("目錄掃描失敗:" + dir.getPath(), e);
        }
        return results;
    }

    /**
     * 并行掃描多個路徑(文件或目錄),使用線程池
     */
    public static List<FilterResult> filterPaths(
            List<File> paths, Long minBytes, Long maxBytes, int threadCount) {
        ExecutorService pool = Executors.newFixedThreadPool(threadCount);
        List<Future<List<FilterResult>>> futures = new ArrayList<>();
        for (File path : paths) {
            futures.add(pool.submit(() -> {
                if (path.isDirectory()) {
                    return filterDirectory(path, minBytes, maxBytes);
                } else if (path.isFile()) {
                    FilterResult r = filter(path, minBytes, maxBytes);
                    return r != null ? Collections.singletonList(r) : Collections.emptyList();
                } else {
                    throw new FilterException("路徑不存在:" + path.getPath());
                }
            }));
        }
        List<FilterResult> all = new ArrayList<>();
        for (Future<List<FilterResult>> f : futures) {
            try {
                all.addAll(f.get());
            } catch (Exception e) {
                System.err.println("任務執(zhí)行失?。? + e.getMessage());
            }
        }
        pool.shutdown();
        return all;
    }
}

// ============================================================================
// 文件:Main.java
// 包名:com.example.filesizefilter
// 功能:命令行入口,解析參數(shù)、調(diào)用過濾邏輯、輸出結(jié)果(支持排序與格式化導出)
// ============================================================================
package com.example.filesizefilter;

import java.io.*;
import java.util.*;
import com.example.filesizefilter.exception.FilterException;

public class Main {
    private static void printHelp() {
        System.out.println("Usage: java -jar filesizefilter.jar [options] <path1> <path2> ...");
        System.out.println("Options:");
        System.out.println("  --min <size>       最小閾值,如 10MB");
        System.out.println("  --max <size>       最大閾值,如 1GB");
        System.out.println("  -t, --threads <n>  并行線程數(shù),默認 4");
        System.out.println("  -s, --sort <asc|desc>  按大小升序或降序排序,默認 asc");
        System.out.println("  -o, --output <file>    導出結(jié)果到文件(CSV 格式),默認輸出到控制臺");
        System.out.println("  -h, --help         顯示幫助信息");
    }

    public static void main(String[] args) {
        if (args.length == 0) { printHelp(); return; }
        Long minBytes = null, maxBytes = null;
        int threads = 4;
        boolean asc = true;
        String outputPath = null;
        List<String> paths = new ArrayList<>();

        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "--min": minBytes = SizeParser.parse(args[++i]); break;
                case "--max": maxBytes = SizeParser.parse(args[++i]); break;
                case "-t": case "--threads": threads = Integer.parseInt(args[++i]); break;
                case "-s": case "--sort":
                    asc = args[++i].equalsIgnoreCase("asc"); break;
                case "-o": case "--output": outputPath = args[++i]; break;
                case "-h": case "--help": printHelp(); return;
                default: paths.add(args[i]);
            }
        }
        if (paths.isEmpty()) { System.err.println("未指定路徑"); printHelp(); return; }

        List<File> fileList = new ArrayList<>();
        for (String p : paths) fileList.add(new File(p));

        try {
            List<FilterResult> results = FileSizeFilter.filterPaths(
                fileList, minBytes, maxBytes, threads);

            // 排序
            results.sort(Comparator.comparingLong(FilterResult::getSize));
            if (!asc) Collections.reverse(results);

            // 輸出
            if (outputPath == null) {
                for (FilterResult r : results) {
                    System.out.printf("%s, %d%n", r.getFile().getPath(), r.getSize());
                }
            } else {
                try (PrintWriter pw = new PrintWriter(new FileWriter(outputPath))) {
                    pw.println("文件路徑,大小(字節(jié))");
                    for (FilterResult r : results) {
                        pw.printf("%s,%d%n", r.getFile().getPath(), r.getSize());
                    }
                }
                System.out.println("已導出到 " + outputPath);
            }
        } catch (FilterException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

// ============================================================================
// 文件:FilterException.java
// 包名:com.example.filesizefilter.exception
// 功能:統(tǒng)一異常類型,用于包裝解析與過濾過程中的錯誤
// ============================================================================
package com.example.filesizefilter.exception;

public class FilterException extends RuntimeException {
    public FilterException(String msg) { super(msg); }
    public FilterException(String msg, Throwable cause) { super(msg, cause); }
}

六、代碼詳細解讀

1.SizeParser

  • 利用正則表達式解析用戶輸入的字符串,支持整數(shù)和小數(shù)部分,并識別單位(B/KB/MB/GB),將其換算為字節(jié)數(shù);
  • 對不符合格式的輸入拋出 FilterException,便于上層捕獲并提示。

2.FilterResult

簡單的 POJO,封裝被過濾文件 File 對象與其大小 long size,便于統(tǒng)一返回與后續(xù)排序、輸出處理。

3.FileSizeFilter

  • filter(File, Long, Long):針對單個文件進行大小判斷;
  • filterDirectory:使用 Files.walkFileTree 遞歸掃描目錄,按文件屬性 BasicFileAttributes 獲取文件大小并篩選,同時對訪問失敗的文件打印錯誤日志;
  • filterPaths:將多個路徑(文件或目錄)分配給線程池并行執(zhí)行,保證性能,同時收集所有結(jié)果。

4.Main(命令行入口)

  • 解析命令行參數(shù):最小/最大閾值、線程數(shù)、排序規(guī)則、輸出文件路徑以及待掃描路徑列表;
  • 調(diào)用 FileSizeFilter.filterPaths 獲取 FilterResult 列表,按大小升降序排序,輸出到控制臺或?qū)С鰹?CSV 文件;
  • 對無效輸入或運行錯誤進行友好提示。

5.FilterException

統(tǒng)一封裝所有解析與掃描過程中的異常,簡化錯誤處理與信息傳播。

七、項目詳細總結(jié)

本文以“Java 實現(xiàn)文件大小過濾”為主題,設計并實現(xiàn)了一個通用、高性能的文件大小篩選工具。主要包含:

  • 靈活閾值解析:支持多種單位和小數(shù)格式,方便用戶以熟悉的方式指定閾值;
  • 目錄遞歸與并行處理:結(jié)合 Files.walkFileTree 與線程池,實現(xiàn)單線程與多線程兩種掃描模式,兼顧易用性與性能;
  • 排序與輸出:按用戶需求支持升序/降序排序,并可輸出到控制臺或 CSV 文件,方便后續(xù)數(shù)據(jù)分析;
  • 健壯異常處理:對無效輸入、文件訪問失敗等場景進行捕獲與提示,保證工具的可用性;
  • 可擴展設計:后續(xù)可增加更多過濾條件(如日期、擴展名),或?qū)С?JSON/HTML 等格式。

八、項目常見問題及解答

1.如何只指定最小閾值,不限制最大?

在命令行中只傳入 --min 參數(shù),不傳 --max,即可過濾出所有大于等于該值的文件。

2.目錄中文件過多,掃描卡頓怎么辦?

可通過 -t 參數(shù)增加線程數(shù);或改用更高效的 ForkJoinPool 分支并行模型以提高 I/O 利用率。

3.如何導出為 JSON 格式?

Main 中添加對 --format=json 的支持,使用 Jackson 將 results 序列化為 JSON 并輸出。

4.掃描過程中遇到權限不足的文件會如何處理?

filterDirectory 中的 visitFileFailed 會打印錯誤日志并繼續(xù),工具默認忽略不可訪問文件,避免中斷整個掃描。

5.能否將該模塊作為庫集成到其他項目?

直接將 SizeParserFileSizeFilter 等類復制到項目中,或打包為 Jar,在 pom.xml 中添加依賴即可使用其 API。

九、擴展方向與性能優(yōu)化

1.基于 NIO2 異步 I/O

采用 AsynchronousFileChannel 進行非阻塞讀取,并結(jié)合 CompletableFuture 管理回調(diào),減少阻塞等待;

2.基于 Fork/Join 的分支掃描

將目錄拆分為子任務,使用 RecursiveTask 并行調(diào)用,提高在多核環(huán)境下的掃描速度;

3.更多過濾條件

支持按最后修改時間、文件類型(擴展名/正則匹配)、文件所有者等多維度過濾;

4.導出多種格式

在命令行中加入 --format 選項,可導出 CSV、JSON、XML、HTML 表格等格式,滿足不同需求;

5.監(jiān)控與變更通知

結(jié)合 WatchService 實時監(jiān)控目錄中文件變化,并在符合閾值條件時發(fā)送郵件、Webhook 通知或日志告警;

6.GUI 圖形化工具

基于 Swing 或 JavaFX 開發(fā)可視化客戶端,用戶通過交互界面配置閾值、路徑和導出方式;

7.集成定時任務

將工具封裝為 Spring Boot 應用,定時執(zhí)行大小過濾并自動清理或歸檔,形成完整的文件管理服務。

到此這篇關于使用Java實現(xiàn)文件大小過濾功能(附源碼)的文章就介紹到這了,更多相關Java文件過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java SE求解漢諾塔問題的示例代碼

    Java SE求解漢諾塔問題的示例代碼

    漢諾塔問題是一個經(jīng)典的問題。漢諾塔(Hanoi Tower),又稱河內(nèi)塔,源于印度一個古老傳說。本文將用Java SE求解這一問題,感興趣的可以學習一下
    2022-03-03
  • Java設計模式之抽象工廠模式詳解

    Java設計模式之抽象工廠模式詳解

    這篇文章主要介紹了Java設計模式之抽象工廠模式詳解,抽象工廠是一種為訪問類提供一個創(chuàng)建一組相關或相互依賴對象的接口,且訪問類無須指定所要產(chǎn)品的具體類就能得到同族的、不同等級的產(chǎn)品的模式結(jié)構,需要的朋友可以參考下
    2023-09-09
  • java批量解析微信dat文件

    java批量解析微信dat文件

    這篇文章主要為大家詳細介紹了java批量解析微信dat文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 詳解MyBatis延遲加載是如何實現(xiàn)的

    詳解MyBatis延遲加載是如何實現(xiàn)的

    MyBatis 的延遲加載(懶加載)特性允許在需要使用關聯(lián)對象數(shù)據(jù)時才進行加載,而不是在執(zhí)行主查詢時就加載所有相關數(shù)據(jù),我們將通過以下幾個方面來深入了解MyBatis的延遲加載實現(xiàn)機制,需要的朋友可以參考下
    2024-07-07
  • Spring Properties的使用和配置方法

    Spring Properties的使用和配置方法

    這篇文章主要介紹了Spring Properties的使用和配置方法,本文不是原理分析、源碼分析文章,只是希望可以幫助讀者更好地理解和使用 Spring Properties,有興趣的可以了解一下
    2018-01-01
  • Jtable和JTree的寫法示例代碼

    Jtable和JTree的寫法示例代碼

    這篇文章主要介紹了Jtable和JTree的基本概念,常用構造方法,以及二者的通用寫法,需要的朋友可以了解下。
    2017-09-09
  • springboot接入微信app支付的方法

    springboot接入微信app支付的方法

    本文使用springboot集成微信支付服務,包含微信統(tǒng)一支付訂單接口,以及支付回調(diào)接口等,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • Mybatis-Plus自動填充更新操作相關字段的實現(xiàn)

    Mybatis-Plus自動填充更新操作相關字段的實現(xiàn)

    這篇文章主要介紹了Mybatis-Plus自動填充更新操作相關字段的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java中類賦值的解釋實例詳解

    Java中類賦值的解釋實例詳解

    這篇文章主要介紹了Java中類賦值的解釋實例詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • SpringBoot中使用定時任務schedule詳解

    SpringBoot中使用定時任務schedule詳解

    文章介紹了如何在Spring應用中使用@EnableScheduling注解啟用定時任務,并創(chuàng)建一個配置類來定義定時任務的執(zhí)行,文章還詳細解釋了Cron表達式的基本語法,并提供了多個常用的Cron表達式示例,以幫助讀者理解和應用定時任務
    2025-11-11

最新評論

大竹县| 司法| 苍溪县| 长丰县| 上饶县| 西乌| 霍城县| 甘洛县| 佳木斯市| 平度市| 海兴县| 长沙市| 台中市| 正定县| 尉氏县| 永仁县| 崇明县| 静安区| 延边| 陆川县| 昔阳县| 秀山| 毕节市| 海丰县| 独山县| 镇沅| 松潘县| 原阳县| 芮城县| 富川| 清徐县| 舟曲县| 临颍县| 繁峙县| 兴安盟| 巫山县| 黑山县| 灌阳县| 西乌| 姚安县| 星子县|