Pārlūkot izejas kodu

采用apache-common-io包简化所有的文件下载io操作

kl 4 gadi atpakaļ
vecāks
revīzija
4ec4e7b398

+ 2 - 2
server/src/main/java/cn/keking/config/SchedulerCleanConfig.java

@@ -1,7 +1,7 @@
 package cn.keking.config;
 
 import cn.keking.service.cache.CacheService;
-import cn.keking.utils.FileUtils;
+import cn.keking.utils.KkFileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@@ -31,7 +31,7 @@ public class SchedulerCleanConfig {
     public void clean() {
         logger.info("Cache clean start");
         cacheService.cleanCache();
-        FileUtils.deleteDirectory(fileDir);
+        KkFileUtils.deleteDirectory(fileDir);
         logger.info("Cache clean end");
     }
 }

+ 5 - 5
server/src/main/java/cn/keking/service/CompressFileReader.java

@@ -2,7 +2,7 @@ package cn.keking.service;
 
 import cn.keking.config.ConfigConstants;
 import cn.keking.model.FileType;
-import cn.keking.utils.FileUtils;
+import cn.keking.utils.KkFileUtils;
 import cn.keking.web.filter.BaseUrlFilter;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -48,7 +48,7 @@ public class CompressFileReader {
         String baseUrl = BaseUrlFilter.getBaseUrl();
         String archiveFileName = fileHandlerService.getFileNameFromPath(filePath);
         try {
-            ZipFile zipFile = new ZipFile(filePath, FileUtils.getFileEncode(filePath));
+            ZipFile zipFile = new ZipFile(filePath, KkFileUtils.getFileEncode(filePath));
             Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
             // 排序
             entries = sortZipEntries(entries);
@@ -382,7 +382,7 @@ public class CompressFileReader {
             } catch (IOException e) {
                 e.printStackTrace();
             }
-            FileUtils.deleteFileByPath(filePath);
+            KkFileUtils.deleteFileByPath(filePath);
         }
 
         private void extractZipFile(String childName, InputStream zipFile) {
@@ -439,7 +439,7 @@ public class CompressFileReader {
             } catch (IOException e) {
                 e.printStackTrace();
             }
-            FileUtils.deleteFileByPath(filePath);
+            KkFileUtils.deleteFileByPath(filePath);
         }
     }
 
@@ -468,7 +468,7 @@ public class CompressFileReader {
             } catch (IOException e) {
                 e.printStackTrace();
             }
-            FileUtils.deleteFileByPath(filePath);
+            KkFileUtils.deleteFileByPath(filePath);
         }
 
         private void extractRarFile(String childName, FileHeader header, Archive archive) {

+ 2 - 2
server/src/main/java/cn/keking/service/FileHandlerService.java

@@ -4,7 +4,7 @@ import cn.keking.config.ConfigConstants;
 import cn.keking.model.FileAttribute;
 import cn.keking.model.FileType;
 import cn.keking.service.cache.CacheService;
-import cn.keking.utils.FileUtils;
+import cn.keking.utils.KkFileUtils;
 import cn.keking.utils.WebUtils;
 import com.aspose.cad.Color;
 import com.aspose.cad.fileformats.cad.CadDrawTypeMode;
@@ -263,7 +263,7 @@ public class FileHandlerService {
         if (StringUtils.hasText(fullFileName)) {
             fileName = fullFileName;
             type = FileType.typeFromFileName(fullFileName);
-            suffix = FileUtils.suffixFromFileName(fullFileName);
+            suffix = KkFileUtils.suffixFromFileName(fullFileName);
         } else {
             fileName = WebUtils.getFileNameFromURL(url);
             type = FileType.typeFromUrl(url);

+ 4 - 3
server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java

@@ -4,6 +4,7 @@ import cn.keking.model.FileAttribute;
 import cn.keking.model.ReturnResponse;
 import cn.keking.service.FilePreview;
 import cn.keking.utils.DownloadUtils;
+import cn.keking.utils.KkFileUtils;
 import org.apache.commons.io.FileUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.ui.Model;
@@ -11,7 +12,6 @@ import org.springframework.util.Base64Utils;
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 
 /**
  * Created by kl on 2018/1/17.
@@ -35,8 +35,9 @@ public class SimTextFilePreviewImpl implements FilePreview {
         }
         try {
             File originFile = new File(response.getContent());
-            String xmlString = FileUtils.readFileToString(originFile, StandardCharsets.UTF_8);
-            model.addAttribute("textData", Base64Utils.encodeToString(xmlString.getBytes(StandardCharsets.UTF_8)));
+            String charset = KkFileUtils.getFileEncode(originFile);
+            String xmlString = FileUtils.readFileToString(originFile, charset);
+            model.addAttribute("textData", Base64Utils.encodeToString(xmlString.getBytes(charset)));
         } catch (IOException e) {
             return otherFilePreview.notSupportedFile(model, fileAttribute, e.getLocalizedMessage());
         }

+ 28 - 97
server/src/main/java/cn/keking/utils/DownloadUtils.java

@@ -2,17 +2,19 @@ package cn.keking.utils;
 
 import cn.keking.config.ConfigConstants;
 import cn.keking.model.FileAttribute;
-import cn.keking.model.FileType;
 import cn.keking.model.ReturnResponse;
 import io.mola.galimatias.GalimatiasParseException;
+import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.*;
 import java.net.*;
-import java.nio.charset.StandardCharsets;
 import java.util.UUID;
 
+import static cn.keking.utils.KkFileUtils.isFtpUrl;
+import static cn.keking.utils.KkFileUtils.isHttpUrl;
+
 /**
  * @author yudian-it
  */
@@ -31,42 +33,26 @@ public class DownloadUtils {
      */
     public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
         String urlStr = fileAttribute.getUrl();
-        String type = fileAttribute.getSuffix();
         ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
-        UUID uuid = UUID.randomUUID();
-        if (null == fileName) {
-            fileName = uuid + "." + type;
-        } else { // 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
-            fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
-        }
-        String realPath = fileDir + fileName;
-        File dirFile = new File(fileDir);
-        if (!dirFile.exists() && !dirFile.mkdirs()) {
-            logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
-        }
+        String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
         try {
-            URL url = new URL(urlStr);
-            if (url.getProtocol() != null && (url.getProtocol().toLowerCase().startsWith("file") || url.getProtocol().toLowerCase().startsWith("http"))) {
-                byte[] bytes = getBytesFromUrl(urlStr);
-                OutputStream os = new FileOutputStream(realPath);
-                saveBytesToOutStream(bytes, os);
-            } else if (url.getProtocol() != null && "ftp".equalsIgnoreCase(url.getProtocol())) {
+            URL url = WebUtils.normalizedURL(urlStr);
+            if (isHttpUrl(url)) {
+                File realFile = new File(realPath);
+                FileUtils.copyURLToFile(url, realFile);
+            } else if (isFtpUrl(url)) {
                 String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
                 String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
                 String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
                 FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
             } else {
                 response.setCode(1);
-                response.setContent(null);
                 response.setMsg("url不能识别url" + urlStr);
             }
             response.setContent(realPath);
             response.setMsg(fileName);
-            if (FileType.simText.equals(fileAttribute.getType())) {
-                convertTextPlainFileCharsetToUtf8(realPath);
-            }
             return response;
-        } catch (IOException e) {
+        } catch (IOException | GalimatiasParseException e) {
             logger.error("文件下载失败,url:{}", urlStr, e);
             response.setCode(1);
             response.setContent(null);
@@ -79,82 +65,27 @@ public class DownloadUtils {
         }
     }
 
-    public static byte[] getBytesFromUrl(String urlStr) throws IOException {
-        InputStream is = getInputStreamFromUrl(urlStr);
-        if (is == null) {
-            is = getInputStreamFromUrl(urlStr);
-            if (is == null) {
-                logger.error("文件下载异常:url:{}", urlStr);
-                throw new IOException("文件下载异常:url:" + urlStr);
-            }
-        }
-        return getBytesFromStream(is);
-    }
-
-    public static void saveBytesToOutStream(byte[] b, OutputStream os) throws IOException {
-        os.write(b);
-        os.close();
-    }
-
-    private static InputStream getInputStreamFromUrl(String urlStr) {
-        try {
-
-            URL url = io.mola.galimatias.URL.parse(urlStr).toJavaURL();
-            URLConnection connection = url.openConnection();
-            if (connection instanceof HttpURLConnection) {
-                connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
-            }
-            return connection.getInputStream();
-        } catch (IOException | GalimatiasParseException e) {
-            logger.warn("连接url异常:url:{}", urlStr);
-            return null;
-        }
-    }
-
-    private static byte[] getBytesFromStream(InputStream is) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int len;
-        while ((len = is.read(buffer)) != -1) {
-            baos.write(buffer, 0, len);
-        }
-        byte[] b = baos.toByteArray();
-        is.close();
-        baos.close();
-        return b;
-    }
 
     /**
-     * 转换文本文件编码为utf8
-     * 探测源文件编码,探测到编码切不为utf8则进行转码
+     * 获取真实文件绝对路径
      *
-     * @param filePath 文件路径
+     * @param fileName 文件名
+     * @return 文件路径
      */
-    private static void convertTextPlainFileCharsetToUtf8(String filePath) throws IOException {
-        File sourceFile = new File(filePath);
-        if (sourceFile.exists() && sourceFile.isFile() && sourceFile.canRead()) {
-            String encoding = FileUtils.getFileEncode(filePath);
-            if (!FileUtils.DEFAULT_FILE_ENCODING.equals(encoding)) {
-                // 不为utf8,进行转码
-                File tmpUtf8File = new File(filePath + ".utf8");
-                Writer writer = new OutputStreamWriter(new FileOutputStream(tmpUtf8File), StandardCharsets.UTF_8);
-                Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), encoding));
-                char[] buf = new char[1024];
-                int read;
-                while ((read = reader.read(buf)) > 0) {
-                    writer.write(buf, 0, read);
-                }
-                reader.close();
-                writer.close();
-                // 删除源文件
-                if (!sourceFile.delete()) {
-                    logger.error("源文件【{}】删除失败,请检查文件目录权限!", filePath);
-                }
-                // 重命名
-                if (tmpUtf8File.renameTo(sourceFile)) {
-                    logger.error("临时文件【{}】重命名失败,请检查文件路径权限!", tmpUtf8File.getPath());
-                }
-            }
+    private static String getRelFilePath(String fileName, FileAttribute fileAttribute) {
+        String type = fileAttribute.getSuffix();
+        if (null == fileName) {
+            UUID uuid = UUID.randomUUID();
+            fileName = uuid + "." + type;
+        } else { // 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
+            fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
+        }
+        String realPath = fileDir + fileName;
+        File dirFile = new File(fileDir);
+        if (!dirFile.exists() && !dirFile.mkdirs()) {
+            logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
         }
+        return realPath;
     }
+
 }

+ 41 - 12
server/src/main/java/cn/keking/utils/FileUtils.java → server/src/main/java/cn/keking/utils/KkFileUtils.java

@@ -6,19 +6,39 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URL;
 import java.util.Objects;
 
-public class FileUtils {
+public class KkFileUtils {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(KkFileUtils.class);
 
     public static final String DEFAULT_FILE_ENCODING = "UTF-8";
 
+    /**
+     * 判断url是否是http资源
+     *
+     * @param url url
+     * @return 是否http
+     */
+    public static boolean isHttpUrl(URL url) {
+        return url.getProtocol().toLowerCase().startsWith("file") || url.getProtocol().toLowerCase().startsWith("http");
+    }
+
+    /**
+     * 判断url是否是ftp资源
+     *
+     * @param url url
+     * @return 是否ftp
+     */
+    public static boolean isFtpUrl(URL url) {
+        return "ftp".equalsIgnoreCase(url.getProtocol());
+    }
+
     /**
      * 删除单个文件
      *
-     * @param fileName
-     *            要删除的文件的文件名
+     * @param fileName 要删除的文件的文件名
      * @return 单个文件删除成功返回true,否则返回false
      */
     public static boolean deleteFileByName(String fileName) {
@@ -39,17 +59,26 @@ public class FileUtils {
     }
 
     /**
-     * 判断文件编码格式
+     * 检测文件编码格式
      *
      * @param filePath 绝对路径
      * @return 编码格式
      */
     public static String getFileEncode(String filePath) {
-        File file = new File(filePath);
+        return getFileEncode(new File(filePath));
+    }
+
+    /**
+     * 检测文件编码格式
+     *
+     * @param file 检测的文件
+     * @return 编码格式
+     */
+    public static String getFileEncode(File file) {
         CharsetPrinter cp = new CharsetPrinter();
         try {
             String encoding = cp.guessEncoding(file);
-            LOGGER.info("检测到文件【{}】编码: {}", filePath, encoding);
+            LOGGER.info("检测到文件【{}】编码: {}", file.getAbsolutePath(), encoding);
             return encoding;
         } catch (IOException e) {
             LOGGER.warn("文件编码获取失败,采用默认的编码格式:UTF-8", e);
@@ -59,6 +88,7 @@ public class FileUtils {
 
     /**
      * 通过文件名获取文件后缀
+     *
      * @param fileName 文件名称
      * @return 文件后缀
      */
@@ -82,8 +112,7 @@ public class FileUtils {
     /**
      * 删除目录及目录下的文件
      *
-     * @param dir
-     *            要删除的目录的文件路径
+     * @param dir 要删除的目录的文件路径
      * @return 目录删除成功返回true,否则返回false
      */
     public static boolean deleteDirectory(String dir) {
@@ -103,13 +132,13 @@ public class FileUtils {
         for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
             // 删除子文件
             if (files[i].isFile()) {
-                flag = FileUtils.deleteFileByName(files[i].getAbsolutePath());
+                flag = KkFileUtils.deleteFileByName(files[i].getAbsolutePath());
                 if (!flag) {
                     break;
                 }
-            }  else if (files[i].isDirectory()) {
+            } else if (files[i].isDirectory()) {
                 // 删除子目录
-                flag = FileUtils.deleteDirectory(files[i].getAbsolutePath());
+                flag = KkFileUtils.deleteDirectory(files[i].getAbsolutePath());
                 if (!flag) {
                     break;
                 }

+ 15 - 1
server/src/main/java/cn/keking/utils/WebUtils.java

@@ -1,5 +1,9 @@
 package cn.keking.utils;
 
+import io.mola.galimatias.GalimatiasParseException;
+
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -8,6 +12,16 @@ import java.util.Map;
  * create : 2020-12-27 1:30 上午
  **/
 public class WebUtils {
+
+    /**
+     * 获取标准的URL
+     * @param urlStr url
+     * @return 标准的URL
+     */
+    public static URL normalizedURL(String urlStr) throws GalimatiasParseException, MalformedURLException {
+        return io.mola.galimatias.URL.parse(urlStr).toJavaURL();
+    }
+
     /**
      * 获取url中的参数
      *
@@ -81,6 +95,6 @@ public class WebUtils {
     public static String suffixFromUrl(String url) {
         String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
         String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
-        return FileUtils.suffixFromFileName(fileName);
+        return KkFileUtils.suffixFromFileName(fileName);
     }
 }

+ 8 - 4
server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java

@@ -6,8 +6,10 @@ import cn.keking.service.FilePreviewFactory;
 
 import cn.keking.service.cache.CacheService;
 import cn.keking.service.impl.OtherFilePreviewImpl;
-import cn.keking.utils.DownloadUtils;
 import cn.keking.service.FileHandlerService;
+import cn.keking.utils.WebUtils;
+import io.mola.galimatias.GalimatiasParseException;
+import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Controller;
@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
+import java.net.URL;
 import java.util.Arrays;
 import java.util.List;
 
@@ -99,9 +102,10 @@ public class OnlinePreviewController {
     public void getCorsFile(String urlPath, HttpServletResponse response) {
         logger.info("下载跨域pdf文件url:{}", urlPath);
         try {
-            byte[] bytes = DownloadUtils.getBytesFromUrl(urlPath);
-            DownloadUtils.saveBytesToOutStream(bytes, response.getOutputStream());
-        } catch (IOException e) {
+            URL url = WebUtils.normalizedURL(urlPath);
+            byte[] bytes = IOUtils.toByteArray(url);
+            IOUtils.write(bytes, response.getOutputStream());
+        } catch (IOException | GalimatiasParseException e) {
             logger.error("下载跨域pdf文件异常,url:{}", urlPath, e);
         }
     }