Tôi có một tệp văn bản động chọn nội dung từ cơ sở dữ liệu theo truy vấn của người dùng. Tôi phải viết nội dung này vào một tệp văn bản và nén nó vào một thư mục trong một servlet. Làm thế nào tôi nên làm điều này?
Tôi có một tệp văn bản động chọn nội dung từ cơ sở dữ liệu theo truy vấn của người dùng. Tôi phải viết nội dung này vào một tệp văn bản và nén nó vào một thư mục trong một servlet. Làm thế nào tôi nên làm điều này?
Câu trả lời:
Nhìn vào ví dụ này:
StringBuilder sb = new StringBuilder();
sb.append("Test String");
File f = new File("d:\\test.zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
ZipEntry e = new ZipEntry("mytext.txt");
out.putNextEntry(e);
byte[] data = sb.toString().getBytes();
out.write(data, 0, data.length);
out.closeEntry();
out.close();
Điều này sẽ tạo ra một zip trong thư mục gốc D:
có tên test.zip
sẽ chứa một tệp duy nhất được gọi mytext.txt
. Tất nhiên, bạn có thể thêm nhiều mục zip và cũng chỉ định thư mục con như thế này:
ZipEntry e = new ZipEntry("folderName/mytext.txt");
Bạn có thể tìm thêm thông tin về nén với Java tại đây .
sb.toString().getBytes()
tệp ZIP, tôi muốn bạn muốn nó chứa byte của tệp bạn đang nén? Hay tôi đang thiếu một cái gì đó?
Java 7 có ZipFileSystem được tích hợp sẵn, có thể được sử dụng để tạo, ghi và đọc tệp từ tệp zip.
Tài liệu Java: Nhà cung cấp ZipFileSystem
Map<String, String> env = new HashMap<>();
// Create the zip file if it doesn't exist
env.put("create", "true");
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt");
Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");
// Copy a file into the zip file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
.zip
? Tôi cần phải viết một .foo
tệp, được định dạng chính xác như tệp zip, nhưng với một phần mở rộng khác. Tôi biết tôi có thể tạo một .zip
tập tin và đổi tên nó, nhưng chỉ cần tạo nó với đúng tên sẽ đơn giản hơn.
jar:file:
tiền tố để tạo URI.
pathInZipfile
biến, bạn cần tạo 'dir' bên trong kho lưu trữ .zip. Đối với điều này, chỉ cần thêm dòng tiếp theo: Files.createDirectories(pathInZipfile.getParent())
trước khi gọi Files.copy
phương thức.
Để viết tệp ZIP, bạn sử dụng ZipOutputStream. Đối với mỗi mục bạn muốn đặt vào tệp ZIP, bạn tạo một đối tượng ZipEntry. Bạn chuyển tên tệp cho hàm tạo ZipEntry; nó đặt các tham số khác như ngày tệp và phương thức giải nén. Bạn có thể ghi đè các cài đặt này nếu bạn muốn. Sau đó, bạn gọi phương thức putNextEntry của ZipOutputStream để bắt đầu viết một tệp mới. Gửi dữ liệu tệp đến luồng ZIP. Khi bạn đã hoàn tất, hãy gọi closeEntry. Lặp lại cho tất cả các tệp bạn muốn lưu trữ. Đây là một bộ xương mã:
FileOutputStream fout = new FileOutputStream("test.zip");
ZipOutputStream zout = new ZipOutputStream(fout);
for all files
{
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();
}
zout.close();
Dưới đây là mã ví dụ để nén Toàn bộ thư mục (bao gồm các tệp phụ và thư mục con), nó sử dụng tính năng cây tập tin đi bộ của Java NIO.
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipCompress {
public static void compress(String dirPath) {
final Path sourceDir = Paths.get(dirPath);
String zipFileName = dirPath.concat(".zip");
try {
final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = sourceDir.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Để sử dụng, chỉ cần gọi
ZipCompress.compress("target/directoryToCompress");
và bạn sẽ nhận được một thư mục tệp zipToCompress.zip
Bộ điều khiển khởi động mùa xuân, nén các tệp trong một thư mục và có thể được tải xuống.
@RequestMapping(value = "/files.zip")
@ResponseBody
byte[] filesZip() throws IOException {
File dir = new File("./");
File[] filesArray = dir.listFiles();
if (filesArray == null || filesArray.length == 0)
System.out.println(dir.getAbsolutePath() + " have no file!");
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ZipOutputStream zipOut= new ZipOutputStream(bo);
for(File xlsFile:filesArray){
if(!xlsFile.isFile())continue;
ZipEntry zipEntry = new ZipEntry(xlsFile.getName());
zipOut.putNextEntry(zipEntry);
zipOut.write(IOUtils.toByteArray(new FileInputStream(xlsFile)));
zipOut.closeEntry();
}
zipOut.close();
return bo.toByteArray();
}
public static void main(String args[])
{
omtZip("res/", "omt.zip");
}
public static void omtZip(String path,String outputFile)
{
final int BUFFER = 2048;
boolean isEntry = false;
ArrayList<String> directoryList = new ArrayList<String>();
File f = new File(path);
if(f.exists())
{
try {
FileOutputStream fos = new FileOutputStream(outputFile);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte data[] = new byte[BUFFER];
if(f.isDirectory())
{
//This is Directory
do{
String directoryName = "";
if(directoryList.size() > 0)
{
directoryName = directoryList.get(0);
System.out.println("Directory Name At 0 :"+directoryName);
}
String fullPath = path+directoryName;
File fileList = null;
if(directoryList.size() == 0)
{
//Main path (Root Directory)
fileList = f;
}else
{
//Child Directory
fileList = new File(fullPath);
}
String[] filesName = fileList.list();
int totalFiles = filesName.length;
for(int i = 0 ; i < totalFiles ; i++)
{
String name = filesName[i];
File filesOrDir = new File(fullPath+name);
if(filesOrDir.isDirectory())
{
System.out.println("New Directory Entry :"+directoryName+name+"/");
ZipEntry entry = new ZipEntry(directoryName+name+"/");
zos.putNextEntry(entry);
isEntry = true;
directoryList.add(directoryName+name+"/");
}else
{
System.out.println("New File Entry :"+directoryName+name);
ZipEntry entry = new ZipEntry(directoryName+name);
zos.putNextEntry(entry);
isEntry = true;
FileInputStream fileInputStream = new FileInputStream(filesOrDir);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER);
int size = -1;
while( (size = bufferedInputStream.read(data, 0, BUFFER)) != -1 )
{
zos.write(data, 0, size);
}
bufferedInputStream.close();
}
}
if(directoryList.size() > 0 && directoryName.trim().length() > 0)
{
System.out.println("Directory removed :"+directoryName);
directoryList.remove(0);
}
}while(directoryList.size() > 0);
}else
{
//This is File
//Zip this file
System.out.println("Zip this file :"+f.getPath());
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis,BUFFER);
ZipEntry entry = new ZipEntry(f.getName());
zos.putNextEntry(entry);
isEntry = true;
int size = -1 ;
while(( size = bis.read(data,0,BUFFER)) != -1)
{
zos.write(data, 0, size);
}
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
if(isEntry)
{
zos.close();
}else
{
zos = null;
System.out.println("No Entry Found in Zip");
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
}catch(Exception e)
{
e.printStackTrace();
}
}else
{
System.out.println("File or Directory not found");
}
}
}
Đây là cách bạn tạo tệp zip từ tệp nguồn:
String srcFilename = "C:/myfile.txt";
String zipFile = "C:/myfile.zip";
try {
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(srcFilename);
FileInputStream fis = new FileInputStream(srcFile);
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
zos.close();
}
catch (IOException ioe) {
System.out.println("Error creating zip file" + ioe);
}
Tập tin duy nhất:
String filePath = "/absolute/path/file1.txt";
String zipPath = "/absolute/path/output.zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
Nhiều tệp:
List<String> filePaths = Arrays.asList("/absolute/path/file1.txt", "/absolute/path/file2.txt");
String zipPath = "/absolute/path/output.zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
for (String filePath : filePaths) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
}
Bạn có chủ yếu để tạo hai chức năng. Đầu tiên là writeToZipFile () và thứ hai là createdZipfileForOutPut .... và sau đó gọi hàm createdZipfileForOutPut ('tên tệp của .zip') `.
public static void writeToZipFile(String path, ZipOutputStream zipStream)
throws FileNotFoundException, IOException {
System.out.println("Writing file : '" + path + "' to zip file");
File aFile = new File(path);
FileInputStream fis = new FileInputStream(aFile);
ZipEntry zipEntry = new ZipEntry(path);
zipStream.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipStream.write(bytes, 0, length);
}
zipStream.closeEntry();
fis.close();
}
public static void createZipfileForOutPut(String filename) {
String home = System.getProperty("user.home");
// File directory = new File(home + "/Documents/" + "AutomationReport");
File directory = new File("AutomationReport");
if (!directory.exists()) {
directory.mkdir();
}
try {
FileOutputStream fos = new FileOutputStream("Path to your destination" + filename + ".zip");
ZipOutputStream zos = new ZipOutputStream(fos);
writeToZipFile("Path to file which you want to compress / zip", zos);
zos.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Nếu bạn muốn giải nén mà không cần phần mềm, hãy sử dụng mã này. Mã khác với tệp pdf gửi lỗi khi giải nén thủ công
byte[] buffer = new byte[1024];
try
{
FileOutputStream fos = new FileOutputStream("123.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry("file.pdf");
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream("file.pdf");
int len;
while ((len = in.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
Vì tôi phải mất một thời gian để tìm ra nó, tôi nghĩ rằng sẽ rất hữu ích khi đăng giải pháp của mình bằng Java 7+ ZipFileSystem
openZip(runFile);
addToZip(filepath); //loop construct;
zipfs.close();
private void openZip(File runFile) throws IOException {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
env.put("encoding", "UTF-8");
Files.deleteIfExists(runFile.toPath());
zipfs = FileSystems.newFileSystem(URI.create("jar:" + runFile.toURI().toString()), env);
}
private void addToZip(String filename) throws IOException {
Path externalTxtFile = Paths.get(filename).toAbsolutePath();
Path pathInZipfile = zipfs.getPath(filename.substring(filename.lastIndexOf("results"))); //all files to be stored have a common base folder, results/ in my case
if (Files.isDirectory(externalTxtFile)) {
Files.createDirectories(pathInZipfile);
try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalTxtFile)) {
for (Path child : ds) {
addToZip(child.normalize().toString()); //recursive call
}
}
} else {
// copy file to zip file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
}
public static void zipFromTxt(String zipFilePath, String txtFilePath) {
Assert.notNull(zipFilePath, "Zip file path is required");
Assert.notNull(txtFilePath, "Txt file path is required");
zipFromTxt(new File(zipFilePath), new File(txtFilePath));
}
public static void zipFromTxt(File zipFile, File txtFile) {
ZipOutputStream out = null;
FileInputStream in = null;
try {
Assert.notNull(zipFile, "Zip file is required");
Assert.notNull(txtFile, "Txt file is required");
out = new ZipOutputStream(new FileOutputStream(zipFile));
in = new FileInputStream(txtFile);
out.putNextEntry(new ZipEntry(txtFile.getName()));
int len;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
} catch (Exception e) {
log.info("Zip from txt occur error,Detail message:{}", e.toString());
} finally {
try {
if (in != null) in.close();
if (out != null) {
out.closeEntry();
out.close();
}
} catch (Exception e) {
log.info("Zip from txt close error,Detail message:{}", e.toString());
}
}
}
Với exportPath
và queryResults
như biến String, khối sau tạo một results.zip
tập tin dưới exportPath
và ghi nội dung của queryResults
một results.txt
tập tin bên trong zip.
URI uri = URI.create("jar:file:" + exportPath + "/results.zip");
Map<String, String> env = Collections.singletonMap("create", "true");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path filePath = zipfs.getPath("/results.txt");
byte[] fileContent = queryResults.getBytes();
Files.write(filePath, fileContent, StandardOpenOption.CREATE);
}
Sử dụng Jeka https://jeka.dev JkPathTree, nó khá đơn giản.
Path wholeDirToZip = Paths.get("dir/to/zip");
Path zipFile = Paths.get("file.zip");
JkPathTree.of(wholeDirToZip).zipTo(zipFile);
Có một tùy chọn khác bằng cách sử dụng zip4j
tại https://github.com/srikanth-lingala/zip4j
Tạo một tệp zip với một tệp trong đó / Thêm một tệp vào một zip hiện có
new ZipFile("filename.zip").addFile("filename.ext");
Hoặc là
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Tạo một tệp zip có nhiều tệp / Thêm nhiều tệp vào một zip hiện có
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Tạo một tệp zip bằng cách thêm một thư mục vào nó / Thêm một thư mục vào một zip hiện có
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Tạo tệp zip từ luồng / Thêm luồng vào zip hiện có
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);
bao gồm trong mẫu mã này? Mục đích của họ là gì?