使用Java編寫(xiě)一個(gè)文件批量重命名工具
背景
在開(kāi)發(fā)移動(dòng)應(yīng)用時(shí),UI設(shè)計(jì)通常會(huì)提供不同分辨率的圖片資源來(lái)適配多種屏幕尺寸。例如,在一個(gè)特定的應(yīng)用場(chǎng)景中,seekbar范圍0-64對(duì)應(yīng)64張圖片,用于滑動(dòng)切換不同的顏色背景。設(shè)計(jì)師提供了"xhdpi", "xxhdpi", "xxxhdpi"三種不同尺寸的圖片集,總共192張圖片。手動(dòng)為這些圖片添加前綴或進(jìn)行其他格式化操作既耗時(shí)又容易出錯(cuò)。因此,為了提高效率并減少人為錯(cuò)誤,這里編寫(xiě)了一個(gè)Java工具類FileRenamer
,用以自動(dòng)化這個(gè)過(guò)程。
處理
1. 文件夾檢查與遍歷
首先,FileRenamer
類定義了新文件名的前綴和源文件夾路徑。然后通過(guò)rename()
方法獲取指定路徑下的文件夾對(duì)象,并驗(yàn)證其有效性。接下來(lái),它遍歷預(yù)設(shè)的子文件夾(如"xhdpi", "xxhdpi", "xxxhdpi"),對(duì)每個(gè)存在的子文件夾調(diào)用processSubFolder()
方法進(jìn)行進(jìn)一步處理。
2. 批量重命名
在processSubFolder()
方法中,程序篩選出所有.png
文件,并使用正則表達(dá)式匹配文件名中的數(shù)字和顏色值。根據(jù)匹配結(jié)果構(gòu)造新的文件名,將原有的數(shù)字部分保留下來(lái),同時(shí)將文件名更改為帶有指定前綴的形式,如從0_color_ffff00.png
到ic_wangyou_color0_ffffff.png
。成功重命名后,程序會(huì)輸出確認(rèn)信息;若失敗,則記錄下錯(cuò)誤。
3. 輸出配置代碼片段
最后,outputCodeSnippet()
方法負(fù)責(zé)生成一段可以復(fù)制粘貼到工程配置中的代碼片段。該方法先過(guò)濾并排序符合新前綴的所有PNG文件,然后構(gòu)造包含這些文件引用的字符串。此外,它還會(huì)列出未被包含的文件,以便開(kāi)發(fā)者檢查是否有遺漏。
完整代碼
通過(guò)上述步驟,FileRenamer
實(shí)現(xiàn)了批量重命名圖片文件的功能,并自動(dòng)生成了配置代碼片段,極大地簡(jiǎn)化了資源管理的工作量。以下是該工具類的完整源碼:
package com.wang.you.util; import java.io.File; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; public class FileRenamer { private static final String NEW_PREFIX = "ic_wangyou_color"; private static final String FOLDER_PATH = "/storage/emulated/0/wangyou"; public static void rename() { File folder = new File(FOLDER_PATH); if (!folder.exists() || !folder.isDirectory()) { System.out.println("指定的路徑不是一個(gè)有效的文件夾!"); return; } String[] subFolders = {"xhdpi", "xxhdpi", "xxxhdpi"}; for (String subFolderName : subFolders) { File subFolder = new File(folder, subFolderName); if (subFolder.exists() && subFolder.isDirectory()) { processSubFolder(subFolder); } else { System.out.println("子文件夾 " + subFolderName + " 不存在或不是一個(gè)有效的文件夾!"); } } } private static void processSubFolder(File subFolder) { File[] files = subFolder.listFiles((dir, name) -> name.toLowerCase().endsWith(".png")); if (files == null || files.length == 0) { System.out.println("在文件夾 " + subFolder.getName() + " 中沒(méi)有找到任何 .png 文件!"); return; } for (File oldFile : files) { String oldFileName = oldFile.getName(); Pattern pattern = Pattern.compile("(\\d+)_(\\w+\\.png)"); Matcher matcher = pattern.matcher(oldFileName); if (matcher.matches()) { String numberPart = matcher.group(1); String colorValueWithExt = matcher.group(2); String colorValue = colorValueWithExt.split("\\.")[0]; String newFileName = NEW_PREFIX + numberPart + "_" + colorValue + ".png"; File newFile = new File(subFolder, newFileName); if (oldFile.renameTo(newFile)) { System.out.println("Renamed: " + oldFileName + " -> " + newFileName); } else { System.out.println("Failed to rename: " + oldFileName); } } else { System.out.println("Invalid file name format: " + oldFileName); } } outputCodeSnippet(subFolder); } private static void outputCodeSnippet(File folder) { Pattern pattern = Pattern.compile("(?<=color)(\\d+)(?=_)"); List<File> allPngFiles = Arrays.stream(folder.listFiles()) .filter(file -> file.getName().toLowerCase().endsWith(".png")) .collect(Collectors.toList()); List<File> renamedFiles = allPngFiles.stream() .filter(file -> file.getName().startsWith(NEW_PREFIX)) .sorted((f1, f2) -> { Matcher m1 = pattern.matcher(f1.getName()); Matcher m2 = pattern.matcher(f2.getName()); if (m1.find() && m2.find()) { return Integer.compare(Integer.parseInt(m1.group()), Integer.parseInt(m2.group())); } return 0; }) .collect(Collectors.toList()); System.out.println("準(zhǔn)備輸出字符串renamedFiles: " + renamedFiles.size()); StringBuilder outputString = new StringBuilder("private final int[] wangyou_colorArr_" + folder.getName() + " = new int[]{\n"); for (File file : renamedFiles) { String fileNameWithoutExtension = file.getName().replaceFirst("[.][^.]+$", ""); outputString.append(" R.mipmap.") .append(fileNameWithoutExtension) .append(",\n"); } if (outputString.toString().endsWith(",\n")) { outputString.setLength(outputString.length() - 2); } outputString.append("\n};"); System.out.println(outputString.toString()); List<File> unmatchedFiles = allPngFiles.stream() .filter(file -> !file.getName().startsWith(NEW_PREFIX)) .collect(Collectors.toList()); if (!unmatchedFiles.isEmpty()) { System.out.println("以下文件未被包含:"); unmatchedFiles.forEach(file -> System.out.println(" " + file.getName())); } } }
這段代碼不僅解決了大批量圖片文件的重命名問(wèn)題,還自動(dòng)生成了對(duì)應(yīng)的資源數(shù)組,使得能夠輕松地在項(xiàng)目中集成這些資源。這里只是一個(gè)示例,當(dāng)然啦,實(shí)際使用要根據(jù)不同的文件名稱去處理,照搬肯定是不行的
到此這篇關(guān)于使用Java編寫(xiě)一個(gè)文件批量重命名工具的文章就介紹到這了,更多相關(guān)Java文件批量重命名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot使用mybatis一對(duì)多的關(guān)聯(lián)查詢問(wèn)題記錄
這篇文章主要介紹了springboot使用mybatis一對(duì)多的關(guān)聯(lián)查詢問(wèn)題記錄,剛好最近有個(gè)需求需要做到關(guān)聯(lián)的查詢,時(shí)間也算充足,所以用sql來(lái)寫(xiě),于是踩了很久坑,終于跳出來(lái)了,小小記錄一下2022-01-01Spring聲明式事務(wù)@Transactional知識(shí)點(diǎn)分享
在本篇文章里小編給大家整理了關(guān)于Spring聲明式事務(wù)@Transactional詳解內(nèi)容,需要的朋友們可以參考下。2020-02-02SpringBoot如何解析應(yīng)用參數(shù)args
文章主要介紹了SpringBoot啟動(dòng)過(guò)程中如何解析`main`函數(shù)中的參數(shù)`args`,包括如何解析命令行參數(shù)、訪問(wèn)選項(xiàng)參數(shù)和非選項(xiàng)參數(shù),接著,介紹了`ApplicationArguments`接口及其方法,感興趣的朋友跟隨小編一起看看吧2024-11-11詳解OpenFeign服務(wù)調(diào)用(微服務(wù))
OpenFeign是Spring Cloud在Feign的基礎(chǔ)上支持了SpringMVC的注解,如@RequesMapping等等,這篇文章主要介紹了OpenFeign服務(wù)調(diào)用的相關(guān)知識(shí),需要的朋友可以參考下2022-07-07java hasNextInt判斷是否為數(shù)字的方法
今天小編就為大家分享一篇java hasNextInt判斷是否為數(shù)字的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07