[compression / download] - Download pdf files to Linux server, and download them from server in batch (zip) and individually to local

Keywords: Java Linux

[business scenario] - connect with the download interface of the third party, download the files provided by the third party to the server, and support batch and single download of files on the server on the client. Generally, there is a special file server for this scenario. This project involves the company's contract and is used by a few people in the company, so it is stored on the project server (you need to specify the download location).

There is not much nonsense. The code is divided into three parts

  1. Download the file to the server;
     
     public void downloadToService(String documentId) {
            if (StringUtil.isBlank(documentId)) {
                throw new BusinessException("Only contracts with download status completed are supported");
            }
            ContractExample example = new ContractExample();
            example.createCriteria().andDocumentIdEqualTo(documentId);
            Contract contract = contractMapper.selectOneByExample(example);
            if (contract == null) {
                throw new BusinessException("Download the contract according to the contract file Id No corresponding contract found");
            }
            FileOutputStream outputDoc = null;
            try {
                // Specify that when downloading files to a folder, you need to build the folder in advance
                String linuxPath = System.getProperty("user.home");
                log.info("Download files to Linux The path for is:{}", linuxPath + "/folder/" + contract.getContractName() + ".pdf");
                outputDoc = new FileOutputStream(linuxPath + "/folder/" + contract.getContractName() + ".pdf");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            signService.downloadDoc(Long.parseLong(documentId), outputDoc);
            safeClose(outputDoc);
            log.info("The contract was downloaded to the server successfully)");
        }

     

  2. Single download is in the form of file stream;
     
    public ResponseEntity<byte[]> download(String contractName, int type) throws IOException {
            String fileName;
            if (type == 1) {
                // Single download pdf file
                fileName = contractName + ".pdf";
            } else {
                // Download zip file in bulk
                fileName = contractName + ".zip";
            }
            //Get file location
            String linuxPath = System.getProperty("user.home");
            log.info("Where users download files:{}", linuxPath + "/folder/" + fileName);
            //Add the file to the input stream
            InputStream in = new FileInputStream(new File(linuxPath + "/folder/" + fileName));
            // Returns the estimated number of bytes remaining that the next method called on this input stream can read (or skip) from this input stream without blocking
            byte[] body = new byte[in.available()];
            //Read into the input stream
            in.read(body);
            //Prevent Chinese miscoding
            fileName = new String(fileName.getBytes("gbk"), "iso8859-1");
            //Set response header
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment;filename=" + fileName);
            return new ResponseEntity<byte[]>(body, headers, HttpStatus.OK);
        }
    
  3. The bulk download is divided into three parts: making the files (multiple) to be downloaded into compressed packages (zip/rar) - "downloading the compressed packages" and "deleting the compressed packages";

     
    public ResponseEntity<byte[]> batchDownload(List<String> contractNames) throws IOException {
            //Get file location
            String linuxPath = System.getProperty("user.home");
            List<File> fileList = new ArrayList<>();
            // Add a directory of files to download to the list of files to compress 
            contractNames.forEach(cn -> fileList.add(new File(linuxPath + "/folder/" + cn + ".pdf")));
            File file = new File(linuxPath + "/folder/XXXX contract.zip");
            FileOutputStream fos = new FileOutputStream(file);
            // Compression tools (to be provided below)
            ZipUtils.toZip(fileList, fos);
            // Call download transfer to foreground
            ResponseEntity<byte[]> response = download("XXXX contract", 2);
            // Delete the downloaded zip package (save space)
            boolean delete = file.delete();
            log.info("Whether the downloaded server file is deleted successfully:{}", delete);
            return response;
        }
    When providing the interface in the background, you can use GET to directly return the responseentity < byte [] >. Here you can try the page request, and the download interface will pop up directly to select the download location, and the foreground will directly thank the url for calling.
     
  4. ZipUtils compression tool class
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.List;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;
    
    public class ZipUtils {
    
        private static final int BUFFER_SIZE = 2 * 1024;
    
        /**
         * Compress to ZIP method 1
         *
         * @param srcDir           Compress folder path
         * @param out              Compressed file output stream
         * @param KeepDirStructure Whether to keep the original directory structure, true: keep the directory structure;
         * false:All files run to the root directory of the compressed package (Note: files with the same name may appear if the directory structure is not preserved, and compression fails)
         */
        public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
                throws RuntimeException {
            long start = System.currentTimeMillis();
            ZipOutputStream zos = null;
            try {
                zos = new ZipOutputStream(out);
                File sourceFile = new File(srcDir);
                compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
                long end = System.currentTimeMillis();
                System.out.println("Compression complete, time consuming:" + (end - start) + " ms");
            } catch (Exception e) {
                throw new RuntimeException("zip error from ZipUtils", e);
            } finally {
                if (zos != null) {
                    try {
                        zos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * Compress to ZIP method 2
         *
         * @param srcFiles List of files to be compressed
         * @param out      Compressed file output stream
         */
        public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
            long start = System.currentTimeMillis();
            ZipOutputStream zos = null;
            try {
                zos = new ZipOutputStream(out);
                for (File srcFile : srcFiles) {
                    byte[] buf = new byte[BUFFER_SIZE];
                    zos.putNextEntry(new ZipEntry(srcFile.getName()));
                    int len;
                    FileInputStream in = new FileInputStream(srcFile);
                    while ((len = in.read(buf)) != -1) {
                        zos.write(buf, 0, len);
                    }
                    zos.closeEntry();
                    in.close();
                }
                long end = System.currentTimeMillis();
                System.out.println("Compression complete, time consuming:" + (end - start) + " ms");
            } catch (Exception e) {
                throw new RuntimeException("zip error from ZipUtils", e);
            } finally {
                if (zos != null) {
                    try {
                        zos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * Recursive compression method
         *
         * @param sourceFile       source file
         * @param zos              zip Output stream
         * @param name             Compressed name
         * @param KeepDirStructure Whether to keep the original directory structure, true: keep the directory structure;
         * false:All files run to the root directory of the compressed package (Note: files with the same name may appear if the directory structure is not preserved, and compression fails)
         */
        private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                     boolean KeepDirStructure) throws Exception {
            byte[] buf = new byte[BUFFER_SIZE];
            if (sourceFile.isFile()) {
                // Add a zip entity to the zip output stream, and the name of the file whose name is the zip entity in the constructor
                zos.putNextEntry(new ZipEntry(name));
                // copy file to zip output stream
                int len;
                FileInputStream in = new FileInputStream(sourceFile);
                while ((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }
                // Complete the entry
                zos.closeEntry();
                in.close();
            } else {
                File[] listFiles = sourceFile.listFiles();
                if (listFiles == null || listFiles.length == 0) {
                    // When you need to keep the original file structure, you need to process the empty folder
                    if (KeepDirStructure) {
                        // Handling of empty folders
                        zos.putNextEntry(new ZipEntry(name + "/"));
                        // No file, no file copy required
                        zos.closeEntry();
                    }
                } else {
                    for (File file : listFiles) {
                        // Determine whether to keep the original file structure
                        if (KeepDirStructure) {
                            // Note: file.getName() needs to be preceded by the name of the parent folder plus a slash,
                            // Otherwise, the original file structure cannot be preserved in the final compression package, that is, all the files run to the root directory of the compression package
                            compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
                        } else {
                            compress(file, zos, file.getName(), KeepDirStructure);
                        }
                    }
                }
            }
        }
    }
    

     

Posted by Todd88 on Sat, 09 Nov 2019 10:58:40 -0800