FileUtil.java 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. package api.common.util;
  2. import lombok.SneakyThrows;
  3. import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
  4. import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
  5. import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
  6. import org.springframework.util.ResourceUtils;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.*;
  9. import java.nio.MappedByteBuffer;
  10. import java.nio.channels.FileChannel;
  11. import java.nio.charset.StandardCharsets;
  12. import java.nio.file.Files;
  13. import java.nio.file.Paths;
  14. import java.util.*;
  15. public class FileUtil {
  16. /**
  17. * 拷贝文件。
  18. */
  19. @SneakyThrows
  20. public static void cp(String sourceFile, String targetFile) {
  21. createParentDirectory(targetFile);
  22. FileInputStream fileInputStream = new FileInputStream(sourceFile);
  23. FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
  24. FileChannel readChannel = fileInputStream.getChannel();
  25. FileChannel writeChannel = fileOutputStream.getChannel();
  26. //自动生成与文件大小相同但不超过 8096 的缓存,即缓存最大为 8096。
  27. writeChannel.transferFrom(readChannel, 0, readChannel.size());
  28. writeChannel.close();
  29. readChannel.close();
  30. fileOutputStream.close();
  31. fileInputStream.close();
  32. }
  33. @SneakyThrows
  34. public static void cpR(String sourceDirectoryPath, String targetDirectoryPath) {
  35. File[] files = new File(sourceDirectoryPath).listFiles();
  36. for (File file : files) {
  37. String sourceFilePath = file.getAbsolutePath();
  38. String targetFilePath = sourceFilePath.replace(sourceDirectoryPath, targetDirectoryPath);
  39. cp(sourceFilePath, targetFilePath);
  40. }
  41. }
  42. /**
  43. * 获得绝对路径
  44. *
  45. * @param parentDirectoryPath 父目录
  46. * @param subStringOfFileName 文件名的子串
  47. * @return 绝对路径
  48. */
  49. @SneakyThrows
  50. public static String getAbsolutePath(String parentDirectoryPath, String subStringOfFileName) {
  51. File parentDirectoryFile = new File(parentDirectoryPath);
  52. if (!parentDirectoryFile.exists()) {
  53. throw new RuntimeException("FileUtil.getAbsolutePath() -- 目录 " + parentDirectoryPath + " 不存在!");
  54. }
  55. File[] files = parentDirectoryFile.listFiles();
  56. if (files == null || files.length == 0) {
  57. throw new RuntimeException("FileUtil.getAbsolutePath() -- 目录 " + parentDirectoryPath + " 下没有文件!");
  58. }
  59. for (File file : files) {
  60. if (file.getName().contains(subStringOfFileName)) {
  61. return file.getAbsolutePath();
  62. }
  63. }
  64. throw new RuntimeException("FileUtil.getAbsolutePath() -- 目录 " + parentDirectoryPath + " 下的文件名包含" + subStringOfFileName + " 的文件不存在!");
  65. }
  66. /**
  67. * 获取所有同一类型的文件列表。
  68. *
  69. * @param rootPath 文件 File 路径。
  70. * @param suffix 文件后缀类型。
  71. */
  72. @SneakyThrows
  73. public static List<String> listAbsolutePathByFiletype(String rootPath, String suffix) {
  74. List<String> result = new LinkedList<>();
  75. File rootFile = new File(rootPath);
  76. //1 判断文件是否存在
  77. if (!rootFile.exists()) {
  78. throw new RuntimeException("FileUtil--listAbsolutePathByFiletype 文件 " + rootPath + " 不存在!");
  79. }
  80. //2 判断是否是文件
  81. if (rootFile.isFile() && rootFile.getName().equals(suffix)) {
  82. return new ArrayList<>(Collections.singletonList(rootPath));
  83. }
  84. //3 判断是否是目录
  85. if (rootFile.isDirectory()) {
  86. File[] children = rootFile.listFiles();
  87. if (children != null) {
  88. for (File child : children) {
  89. result.addAll(listAbsolutePathByFiletype(child.getAbsolutePath(), suffix));
  90. }
  91. }
  92. }
  93. return result;
  94. }
  95. /**
  96. * 获取当前目录下的一级文件全路径列表
  97. * @param path 根路径
  98. * @return 文件全路径列表
  99. */
  100. public static List<String> ls(String path) {
  101. File[] files = new File(path).listFiles();
  102. if (files == null){
  103. throw new RuntimeException("路径不存在!");
  104. }
  105. List<String> result = new ArrayList<>();
  106. for (File file : files) {
  107. result.add(file.getAbsolutePath()) ;
  108. }
  109. return result;
  110. }
  111. @SneakyThrows
  112. public static String read(String path){
  113. return read(getFile(path));
  114. }
  115. public static String cat(String path) throws Exception {
  116. return read(getFile(path));
  117. }
  118. @SneakyThrows
  119. public static String read(File file) throws IOException {
  120. return read(Files.newInputStream(file.toPath()));
  121. }
  122. public static String read(InputStream inputStream) throws IOException {
  123. StringBuilder result = new StringBuilder();
  124. byte[] buf = new byte[4096];//创建字节数组,存储临时读取的数据
  125. int len;//记录数据读取的长度
  126. //循环读取数据
  127. while ((len = inputStream.read(buf)) != -1) { //长度为-1则读取完毕
  128. result.append(new String(buf, 0, len)).append("\n");
  129. }
  130. inputStream.close();
  131. return result.toString();
  132. }
  133. // -------------------------------- A --------------------------------
  134. /**
  135. * 添加文件后缀
  136. *
  137. * @param url 路径
  138. * @return 有后缀名的文件
  139. */
  140. public static String addSeparator(String url) {
  141. if (File.separator.equals(url.charAt(url.length() - 1) + "")) {
  142. return url;
  143. }
  144. return url + File.separator;
  145. }
  146. /**
  147. * 添加文件后缀
  148. *
  149. * @param ambiguousFileName 不确定是否有后缀的文件名
  150. * @return 有后缀名的文件
  151. */
  152. public static String addSuffix(String ambiguousFileName, String suffix) {
  153. if (ambiguousFileName == null || "".equals(ambiguousFileName)) {
  154. throw new RuntimeException("文件名参数为空!");
  155. }
  156. String[] split = ambiguousFileName.split("\\.");
  157. return split[0] + suffix;
  158. }
  159. // -------------------------------- B --------------------------------
  160. // -------------------------------- C --------------------------------
  161. /**
  162. * 检查文件
  163. * 0 代表不存在
  164. * 1 代表是文件
  165. * 2 代表是目录
  166. *
  167. * @param file 文件
  168. * @return 是否正确
  169. */
  170. public static String checkFile(File file) {
  171. if (!file.exists()) {
  172. return "0";
  173. }
  174. if (file.isFile()) {
  175. return "1";
  176. }
  177. if (file.isDirectory()) {
  178. return "2";
  179. }
  180. return null;
  181. }
  182. /**
  183. * 检查文件后缀
  184. *
  185. * @param file 文件
  186. * @param suffix 文件后缀
  187. * @return 是否正确
  188. */
  189. public static boolean checkFileType(File file, String suffix) {
  190. String fileName = file.getName();
  191. int fileNameLength = fileName.length();
  192. int suffixLength = suffix.length();
  193. if (fileNameLength < suffixLength) {
  194. return false;
  195. }
  196. return suffix.equals(fileName.substring(fileNameLength - suffixLength));
  197. }
  198. /**
  199. * 自适应转换文件大小的单位
  200. *
  201. * @param dataSize long 型的文件大小
  202. * @return 带单位的 String 类型文件大小
  203. */
  204. public static String convertUnit(long dataSize) {
  205. String dataSizeStr = null;
  206. if (dataSize >= 0 && dataSize < 1024) {
  207. dataSizeStr = dataSize + "B";
  208. } else if (dataSize >= 1024 && dataSize < 1024 * 1024) {
  209. dataSizeStr = dataSize / 1024 + "KB";
  210. } else if (dataSize >= 1024 * 1024 && dataSize < 1024 * 1024 * 1024) {
  211. dataSizeStr = dataSize / 1024 / 1024 + "MB";
  212. } else if (dataSize >= 1024 * 1024 * 1024 && dataSize < 1024 * 1024 * 1024 * 1024L) {
  213. dataSizeStr = dataSize / 1024 / 1024 / 1024 + "GB";
  214. } else if (dataSize >= 1024 * 1024 * 1024 * 1024L) {
  215. dataSizeStr = dataSize / 1024 / 1024 / 1024 / 1024 + "TB";
  216. }
  217. return dataSizeStr;
  218. }
  219. /**
  220. * 计算目录包含的文件数量
  221. *
  222. * @param directory 目录的 File 对象
  223. * @return 文件数量
  224. */
  225. public static int count(File directory) {
  226. return Objects.requireNonNull(directory.listFiles()).length;
  227. }
  228. /**
  229. * 计算目录包含的文件数量
  230. *
  231. * @param directoryPath 目录的路径
  232. * @return 文件数量
  233. */
  234. public static int count(String directoryPath) throws Exception {
  235. return count(getDirectory(directoryPath));
  236. }
  237. /**
  238. * 复制文件
  239. *
  240. * @param source 原始文件路径
  241. * @param target 目标路径
  242. * @throws Exception 异常
  243. */
  244. public static void copy(String source, String target) throws Exception {
  245. File targetFile = new File(target);
  246. boolean delete = true;
  247. if (targetFile.exists()) {
  248. delete = targetFile.delete();
  249. }
  250. if (delete) {
  251. createParentDirectory(target);
  252. Files.copy(getFile(source).toPath(), new File(target).toPath());
  253. } else {
  254. throw new Exception("删除 " + target + " 失败!");
  255. }
  256. }
  257. /**
  258. * 创建目录
  259. */
  260. public static boolean createDirectory(String path) {
  261. boolean mkdir = false;
  262. File file = new File(path);
  263. if (!file.exists()) {
  264. mkdir = file.mkdirs();
  265. }
  266. return mkdir;
  267. }
  268. /**
  269. * 创建父目录
  270. */
  271. public static boolean createParentDirectory(String path) {
  272. boolean mkdir = false;
  273. File file = new File(path);
  274. if (!file.getParentFile().exists()) {
  275. mkdir = file.getParentFile().mkdirs();
  276. }
  277. return mkdir;
  278. }
  279. /**
  280. * 创建父目录
  281. */
  282. public static boolean createParentDirectory(File file) {
  283. boolean mkdir = true;
  284. if (!file.getParentFile().exists()) {
  285. mkdir = file.getParentFile().mkdirs();
  286. }
  287. return mkdir;
  288. }
  289. /**
  290. * 创建文件。
  291. */
  292. public static boolean createFile(String path) throws IOException {
  293. File file = new File(path);
  294. boolean result = createParentDirectory(file);
  295. if (!file.exists()) {
  296. result = file.createNewFile();
  297. }
  298. return result;
  299. }
  300. /**
  301. * 创建文件。
  302. */
  303. public static boolean createFile(File file) throws IOException {
  304. boolean result = createParentDirectory(file);
  305. if (!file.exists()) {
  306. result = file.createNewFile();
  307. }
  308. return result;
  309. }
  310. /**
  311. * 拷贝文件。
  312. */
  313. public static void copyFile(String readFrom, String writeTo) throws IOException {
  314. createParentDirectory(writeTo);
  315. FileInputStream fileInputStream = new FileInputStream(readFrom);
  316. FileOutputStream fileOutputStream = new FileOutputStream(writeTo);
  317. FileChannel readChannel = fileInputStream.getChannel();
  318. FileChannel writeChannel = fileOutputStream.getChannel();
  319. //自动生成与文件大小相同但不超过 8096 的缓存,即缓存最大为 8096。
  320. writeChannel.transferFrom(readChannel, 0, readChannel.size());
  321. writeChannel.close();
  322. readChannel.close();
  323. fileOutputStream.close();
  324. fileInputStream.close();
  325. }
  326. public static void copyBytes(InputStream in, OutputStream out, int bufferSize) throws IOException {
  327. byte[] buffer = new byte[bufferSize];
  328. for (int bytesRead = in.read(buffer); bytesRead >= 0; bytesRead = in.read(buffer)) {
  329. out.write(buffer, 0, bytesRead);
  330. }
  331. }
  332. // -------------------------------- D --------------------------------
  333. /**
  334. * 供 http 下载使用
  335. *
  336. * @param fileName 文件名
  337. * @param in 输入流
  338. * @param response 响应对象
  339. * @param bufferSize 缓存大小
  340. * @throws IOException 异常
  341. */
  342. public static void downloadForHttp(String fileName, InputStream in, HttpServletResponse response, int bufferSize) throws IOException {
  343. response.setContentType("application/octet-stream;charset=utf-8");
  344. response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
  345. copyBytes(in, response.getOutputStream(), bufferSize);
  346. }
  347. public static Set<String> decompress(InputStream inputStream, String targetDirectoryPath, String fileType) throws IOException {
  348. Set<String> fileList = new HashSet<>();
  349. if (!targetDirectoryPath.endsWith("/")) {
  350. targetDirectoryPath += "/";
  351. }
  352. if (".tar".equals(fileType)) {
  353. TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(inputStream);
  354. TarArchiveEntry entry;
  355. // 将 tar 文件解压到 extractPath 目录下
  356. while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
  357. if (entry.isDirectory()) {
  358. continue;
  359. }
  360. createDirectory(targetDirectoryPath);
  361. File currentFile = new File(targetDirectoryPath + entry.getName());
  362. File parent = currentFile.getParentFile();
  363. if (!parent.exists()) {
  364. boolean mkdirs = parent.mkdirs();
  365. }
  366. fileList.add(currentFile.getAbsolutePath());
  367. // 将文件写出到解压的目录
  368. copyBytes(tarArchiveInputStream, new FileOutputStream(currentFile), 4096);
  369. }
  370. }
  371. if (".tar.gz".equals(fileType)|| ".tgz".equals(fileType)|| ".gz".equals(fileType)) {
  372. TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream((new GzipCompressorInputStream(inputStream)));
  373. TarArchiveEntry entry;
  374. // 将 tar 文件解压到 extractPath 目录下
  375. while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
  376. if (entry.isDirectory()) {
  377. continue;
  378. }
  379. createDirectory(targetDirectoryPath);
  380. File currentFile = new File(targetDirectoryPath + entry.getName());
  381. File parent = currentFile.getParentFile();
  382. if (!parent.exists()) {
  383. boolean mkdirs = parent.mkdirs();
  384. }
  385. fileList.add(currentFile.getAbsolutePath());
  386. // 将文件写出到解压的目录
  387. copyBytes(tarArchiveInputStream, new FileOutputStream(currentFile), 4096);
  388. }
  389. }
  390. inputStream.close();
  391. return fileList;
  392. }
  393. /**
  394. * 扫描压缩包中是否存在指定文件
  395. * @param inputStream
  396. * @param fileType
  397. * @return
  398. * @throws IOException
  399. */
  400. public static boolean scan(InputStream inputStream, String fileType, String targetFileName) throws IOException {
  401. if (".tar".equals(fileType)) {
  402. TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(inputStream);
  403. TarArchiveEntry entry;
  404. // 将 tar 文件解压到 extractPath 目录下
  405. while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
  406. if (entry.getName().contains(targetFileName)){
  407. return true;
  408. }
  409. }
  410. }
  411. if (".tar.gz".equals(fileType)|| ".tgz".equals(fileType)|| ".gz".equals(fileType)) {
  412. TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream((new GzipCompressorInputStream(inputStream)));
  413. TarArchiveEntry entry;
  414. // 将 tar 文件解压到 extractPath 目录下
  415. while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
  416. if (entry.getName().contains(targetFileName)){
  417. return true;
  418. }
  419. }
  420. }
  421. inputStream.close();
  422. return false;
  423. }
  424. // -------------------------------- F --------------------------------
  425. // -------------------------------- G --------------------------------
  426. /**
  427. * 获得去除文件后缀的文件名
  428. */
  429. public static List<String> getAbsolutePathList(File[] files) {
  430. List<String> absolutePathList = new ArrayList<>();
  431. for (File file : files) {
  432. absolutePathList.add(file.getAbsolutePath());
  433. }
  434. return absolutePathList;
  435. }
  436. /**
  437. * 获得目录的 File 对象
  438. */
  439. public static File getDirectory(String path) throws Exception {
  440. // 获取文件
  441. File file = new File(path);
  442. if (!file.exists()) {
  443. throw new Exception("文件" + path + "不存在!");
  444. }
  445. if (!file.isDirectory()) {
  446. throw new Exception("文件" + path + "不是目录!");
  447. }
  448. return file;
  449. }
  450. /**
  451. * 获得去除文件后缀的文件名
  452. */
  453. public static File getFile(String path) throws Exception {
  454. // 获取文件
  455. File file = new File(path);
  456. if (!file.exists()) {
  457. throw new Exception("文件" + path + "不存在!");
  458. }
  459. return file;
  460. }
  461. /**
  462. * 获得去除文件后缀的文件名
  463. */
  464. public static String getFilename(File file) {
  465. return file.getName().split("\\.")[0];
  466. }
  467. /**
  468. * 获得去除文件后缀的文件名
  469. */
  470. public static String getFilename(String path) throws Exception {
  471. return getFilename(getFile(path));
  472. }
  473. /**
  474. * 获得去除文件后缀的文件名
  475. */
  476. public static List<String> getFilenameList(File[] files) {
  477. List<String> fileNameList = new ArrayList<>();
  478. for (File file : files) {
  479. fileNameList.add(file.getName());
  480. }
  481. return fileNameList;
  482. }
  483. /**
  484. * 获取文件行数
  485. *
  486. * @param path 文件路径
  487. * @return 文件行数
  488. * @throws IOException 异常
  489. */
  490. public static long getFileLineNum(String path) throws IOException {
  491. return Files.lines(Paths.get(path)).count();
  492. }
  493. /**
  494. * 获取文件名称
  495. *
  496. * @param path 文件路径
  497. * @return 文件名
  498. */
  499. public static String getFileName(String path) {
  500. return new File(path).getName();
  501. }
  502. /**
  503. * 获取 classpath 文件
  504. *
  505. * @param relativePath 相对路径
  506. */
  507. public static File getResourceFile(String relativePath) throws IOException {
  508. return ResourceUtils.getFile("classpath:" + relativePath);
  509. }
  510. /**
  511. * 获取所有文件列表。
  512. *
  513. * @param root 文件 File 对象。
  514. */
  515. public static List<File> list(File root) throws Exception {
  516. List<File> result = new LinkedList<>();
  517. //1 判断文件是否存在
  518. if (!root.exists()) {
  519. throw new Exception("文件" + root.getAbsolutePath() + "不存在!");
  520. }
  521. //2 判断是否是文件
  522. if (root.isFile()) {
  523. return new ArrayList<>(Collections.singletonList(root));
  524. }
  525. //3 判断是否是目录
  526. if (root.isDirectory()) {
  527. File[] children = root.listFiles();
  528. if (children != null) {
  529. for (File child : children) {
  530. result.addAll(list(child));
  531. }
  532. }
  533. }
  534. return result;
  535. }
  536. /**
  537. * 获取所有文件列表。
  538. *
  539. * @param rootPath 文件 File 对象。
  540. */
  541. public static List<String> list(String rootPath) throws Exception {
  542. List<String> result = new ArrayList<>();
  543. File root = new File(rootPath);
  544. //1 判断文件是否存在
  545. if (!root.exists()) {
  546. throw new Exception("文件" + root.getAbsolutePath() + "不存在!");
  547. }
  548. //2 判断是否是文件
  549. if (root.isFile()) {
  550. return new ArrayList<>(Collections.singletonList(rootPath));
  551. }
  552. //3 判断是否是目录
  553. if (root.isDirectory()) {
  554. File[] children = root.listFiles();
  555. if (children != null) {
  556. for (File child : children) {
  557. result.addAll(list(child.getAbsolutePath()));
  558. }
  559. }
  560. }
  561. return result;
  562. }
  563. public static void deleteFileBySubstring(String parentDirectoryPath,String substringOfFilename){
  564. File[] files = new File(parentDirectoryPath).listFiles();
  565. if(files == null || files.length == 0){
  566. return;
  567. }
  568. for (File file : files) {
  569. if (file.getName().contains(substringOfFilename)){
  570. boolean delete = file.delete();
  571. }
  572. }
  573. }
  574. /**
  575. * 获取所有文件列表。
  576. *
  577. * @param rootPath 文件 File 对象。
  578. */
  579. public static List<String> listAbsolutePath(String rootPath) throws Exception {
  580. List<String> result = new ArrayList<>();
  581. File root = new File(rootPath);
  582. //1 判断文件是否存在
  583. if (!root.exists()) {
  584. throw new Exception("文件" + root.getAbsolutePath() + "不存在!");
  585. }
  586. //2 判断是否是文件
  587. if (root.isFile()) {
  588. return new ArrayList<>(Collections.singletonList(rootPath));
  589. }
  590. //3 判断是否是目录
  591. if (root.isDirectory()) {
  592. File[] children = root.listFiles();
  593. if (children != null) {
  594. for (File child : children) {
  595. result.addAll(list(child.getAbsolutePath()));
  596. }
  597. }
  598. }
  599. return result;
  600. }
  601. /**
  602. * 获取所有同一类型的文件列表。
  603. *
  604. * @param root 文件 File 对象。
  605. * @param suffix 文件后缀类型。
  606. */
  607. public static List<File> listMatchSuffix(File root, String suffix) throws Exception {
  608. List<File> result = new LinkedList<>();
  609. //1 判断文件是否存在
  610. if (!root.exists()) {
  611. throw new Exception("文件" + root.getAbsolutePath() + "不存在!");
  612. }
  613. //2 判断是否是文件
  614. if (root.isFile() && checkFileType(root, suffix)) {
  615. return new ArrayList<>(Collections.singletonList(root));
  616. }
  617. //3 判断是否是目录
  618. if (root.isDirectory()) {
  619. File[] children = root.listFiles();
  620. if (children != null) {
  621. for (File child : children) {
  622. result.addAll(listMatchSuffix(child, suffix));
  623. }
  624. }
  625. }
  626. return result;
  627. }
  628. /**
  629. * 获取所有同一名称的文件列表。
  630. *
  631. * @param root 文件 File 对象。
  632. * @param fullFilename 带后缀的文件名。
  633. */
  634. public static List<File> listMatchName(File root, String fullFilename) throws Exception {
  635. List<File> result = new LinkedList<>();
  636. //1 判断文件是否存在
  637. if (!root.exists()) {
  638. throw new Exception("文件" + root.getAbsolutePath() + "不存在!");
  639. }
  640. //2 判断是否是文件且文件名是否一致
  641. if (root.isFile() && fullFilename.equals(root.getName())) {
  642. return new ArrayList<>(Collections.singletonList(root));
  643. }
  644. //3 判断是否是目录
  645. if (root.isDirectory()) {
  646. File[] children = root.listFiles();
  647. if (children != null) {
  648. for (File child : children) {
  649. result.addAll(listMatchName(child, fullFilename));
  650. }
  651. }
  652. }
  653. return result;
  654. }
  655. /**
  656. * 获得父级文件。
  657. *
  658. * @return 父级文件
  659. */
  660. public static File getParentFile(String path) throws Exception {
  661. return getParentFile(getFile(path));
  662. }
  663. /**
  664. * 获得父级文件。
  665. *
  666. * @return 父级文件
  667. */
  668. public static File getParentFile(File file) {
  669. return file.getParentFile();
  670. }
  671. /**
  672. * 获得父级目录名。
  673. */
  674. public static String getParentDirectoryName(File file) {
  675. return getParentFile(file).getName().split("\\.")[0];
  676. }
  677. /**
  678. * 获得父级目录名。
  679. */
  680. public static String getParentDirectoryName(String path) throws Exception {
  681. return getParentDirectoryName(getFile(path));
  682. }
  683. /**
  684. * 获取路径下的所有文件总大小
  685. */
  686. public static double getSize(File file) throws Exception {
  687. //判断文件是否存在
  688. if (file.exists()) {
  689. //如果是目录则递归计算其内容的总大小
  690. if (file.isDirectory()) {
  691. File[] children = file.listFiles();
  692. if (children == null) {
  693. return 0;
  694. }
  695. double size = 0;
  696. for (File f : children)
  697. size += getSize(f);
  698. return size;
  699. } else {//如果是文件则直接返回其大小,以“兆”为单位
  700. return (double) file.length() / 1024 / 1024;
  701. }
  702. } else {
  703. throw new Exception("文件或者文件夹不存在,请检查路径" + file.getAbsolutePath() + "是否正确!");
  704. }
  705. }
  706. public static String getSuffix(String path) {
  707. String[] split = path.split("\\.");
  708. return split[split.length - 1];
  709. }
  710. /**
  711. * 计算文件大小,递归算法
  712. */
  713. public static long getTotalSizeOfFilesInDir(final File file) throws Exception {
  714. //判断文件是否存在
  715. if (file.exists()) {
  716. if (file.isFile()) {
  717. return file.length();
  718. }
  719. final File[] children = file.listFiles();
  720. long total = 0;
  721. if (children != null) {
  722. for (final File child : children) {
  723. total += getTotalSizeOfFilesInDir(child);
  724. }
  725. }
  726. return total;
  727. } else {
  728. throw new Exception("文件或者文件夹不存在,请检查路径" + file.getAbsolutePath() + "是否正确!");
  729. }
  730. }
  731. // -------------------------------- H --------------------------------
  732. // -------------------------------- I --------------------------------
  733. // -------------------------------- J --------------------------------
  734. // -------------------------------- K --------------------------------
  735. // -------------------------------- L --------------------------------
  736. // -------------------------------- M --------------------------------
  737. /**
  738. * 修改文件。
  739. */
  740. public static void modifyFile(String path, int offset, byte[] bytes) throws IOException {
  741. createFile(path);
  742. RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw");
  743. FileChannel channel = randomAccessFile.getChannel();
  744. MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, offset, bytes.length);
  745. mappedByteBuffer.put(bytes);
  746. channel.close();
  747. }
  748. /**
  749. * 移动文件或者重命名文件
  750. *
  751. * @param source 原始文件路径
  752. * @param target 目标路径
  753. * @return 是否操作成功
  754. * @throws Exception 异常
  755. */
  756. public static boolean mv(String source, String target) throws Exception {
  757. return getFile(source).renameTo(new File(target));
  758. }
  759. // -------------------------------- N --------------------------------
  760. // -------------------------------- O --------------------------------
  761. // -------------------------------- P --------------------------------
  762. // -------------------------------- Q --------------------------------
  763. // -------------------------------- R --------------------------------
  764. public static String readFile(String path) throws Exception {
  765. return readFile(getFile(path));
  766. }
  767. public static String readFile(File file) throws Exception {
  768. BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
  769. StringBuilder stringBuilder = new StringBuilder();
  770. String line;
  771. while ((line = reader.readLine()) != null) {
  772. stringBuilder.append(line);
  773. }
  774. reader.close();
  775. return String.valueOf(stringBuilder);
  776. }
  777. public static String readInputStream(InputStream inputStream) throws Exception {
  778. StringBuilder result = new StringBuilder();
  779. byte[] buf = new byte[1024];//创建字节数组,存储临时读取的数据
  780. int len = 0;//记录数据读取的长度
  781. //循环读取数据
  782. while ((len = inputStream.read(buf)) != -1) { //长度为-1则读取完毕
  783. result.append(new String(buf, 0, len));
  784. }
  785. inputStream.close();
  786. return result.toString();
  787. }
  788. /**
  789. * 删除文件或递归删除目录
  790. * 递归删除目录下的所有文件及子目录下所有文件
  791. */
  792. public static boolean rm(File file) {
  793. if (!file.exists()) {
  794. return false;
  795. } else {
  796. if (file.isDirectory()) {
  797. String[] children = file.list();
  798. if (children != null) {
  799. for (String child : children) {
  800. if (!rm(new File(file, child))) {
  801. return false;
  802. }
  803. }
  804. }
  805. return true;
  806. } else {
  807. return file.delete();
  808. }
  809. }
  810. }
  811. /**
  812. * 删除文件或递归删除目录
  813. * 递归删除目录下的所有文件及子目录下所有文件
  814. */
  815. public static boolean rm(String path) {
  816. return rm(new File(path));
  817. }
  818. // -------------------------------- S --------------------------------
  819. // public static String splicingPath(String... paths) {
  820. // StringBuilder result = new StringBuilder();
  821. // for (int i = 0; i < paths.length; i++) {
  822. // if (i == 0) {
  823. // if ("/".equals(paths[0].charAt(paths.length - 1) + "")) {
  824. // String substring = paths[0].substring(0, paths[0].length() - 2);
  825. // result.append(substring);
  826. // } else {
  827. // result.append(paths[0]);
  828. // }
  829. // } else {
  830. // String[] split = paths[i].split("/");
  831. //
  832. // for (String s : split) {
  833. // if (s != null && !"".equals(s)) {
  834. // result.append("/").append(s);
  835. // }
  836. // }
  837. // }
  838. // }
  839. // return result.toString();
  840. // }
  841. // -------------------------------- T --------------------------------
  842. // -------------------------------- U --------------------------------
  843. // -------------------------------- V --------------------------------
  844. // -------------------------------- W --------------------------------
  845. /**
  846. * 将字符串保存为本地文件
  847. */
  848. @SneakyThrows
  849. public static void writeStringToLocalFile(String string, String filePath) throws IOException {
  850. writeInputStreamToLocalFile(new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8)), filePath);
  851. }
  852. /**
  853. * 将字符串保存为本地文件
  854. */
  855. @SneakyThrows
  856. public static void writeStringToLocalFile(String string, String filePath, int bufferLength) throws IOException {
  857. writeInputStreamToLocalFile(new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8)), filePath, bufferLength);
  858. }
  859. /**
  860. * 将输入流保存为本地文件
  861. */
  862. public static void writeInputStreamToLocalFile(InputStream inputStream, String filePath) throws IOException {
  863. writeInputStreamToLocalFile(inputStream, filePath, 4096);
  864. }
  865. /**
  866. * 将输入流保存为本地文件
  867. */
  868. public static void writeInputStreamToLocalFile(InputStream inputStream, String filePath, int bufferLength) throws IOException {
  869. BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
  870. byte[] data = new byte[bufferLength];
  871. int dataLength;
  872. File file = new File(filePath);
  873. createParentDirectory(file);
  874. BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file, false));
  875. while ((dataLength = bufferedInputStream.read(data)) != -1) {
  876. bufferedOutputStream.write(data, 0, dataLength);
  877. }
  878. bufferedOutputStream.close();
  879. bufferedInputStream.close();
  880. }
  881. /**
  882. * 将输入流保存为本地文件
  883. */
  884. public static void writeInputStreamToLocalDirectory(InputStream inputStream, String directoryPath, String filename) throws IOException {
  885. BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
  886. byte[] data = new byte[1024];
  887. int dataLength;
  888. File file = new File(directoryPath + File.separator + filename);
  889. createDirectory(directoryPath);
  890. createFile(file);
  891. BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file, false));
  892. while ((dataLength = bufferedInputStream.read(data)) != -1) {
  893. bufferedOutputStream.write(data, 0, dataLength);
  894. }
  895. bufferedOutputStream.close();
  896. bufferedInputStream.close();
  897. }
  898. }