У мене є динамічний текстовий файл, який вибирає вміст із бази даних відповідно до запиту користувача. Мені потрібно записати цей вміст у текстовий файл і зафіксувати його в папці сервлета. Як мені це зробити?
У мене є динамічний текстовий файл, який вибирає вміст із бази даних відповідно до запиту користувача. Мені потрібно записати цей вміст у текстовий файл і зафіксувати його в папці сервлета. Як мені це зробити?
Відповіді:
Подивіться на цей приклад:
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();
Це створить ZIP у корені з D:
іменем, test.zip
який буде містити один названий файл mytext.txt
. Звичайно, ви можете додати більше поштових записів, а також вказати такий підкаталог:
ZipEntry e = new ZipEntry("folderName/mytext.txt");
Ви можете знайти більше інформації про стиснення з Java тут .
sb.toString().getBytes()
файл ZIP, я б очікував, що ви хочете, щоб він містив байти файлу, який ви копіюєте? Або я щось пропускаю?
У Java 7 вбудована система ZipFileSystem, яку можна використовувати для створення, запису та читання файлів із zip-файлів.
Java Doc: постачальник 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
? Мені потрібно написати .foo
файл, який відформатований точно як zip-файл, але з іншим розширенням. Я знаю, що міг би створити .zip
файл і перейменувати його, але просто створити його з потрібним іменем було б простіше.
jar:file:
префікс для створення URI.
pathInZipfile
змінній, вам потрібно створити "dir" всередині архіву .zip. Для цього просто додайте наступний рядок: Files.createDirectories(pathInZipfile.getParent())
перед тим, як викликати Files.copy
метод.
Щоб написати ZIP-файл, ви використовуєте ZipOutputStream. Для кожного запису, який ви хочете помістити у файл ZIP, ви створюєте об'єкт ZipEntry. Ви передаєте ім'я файлу конструктору ZipEntry; він встановлює інші параметри, такі як дата файлу та метод декомпресії. Якщо ви хочете, ви можете змінити ці налаштування. Потім ви викликаєте метод putNextEntry ZipOutputStream, щоб почати писати новий файл. Надішліть дані файлу до потоку ZIP. Коли ви закінчите, зателефонуйте closeEntry. Повторіть для всіх файлів, які потрібно зберегти. Ось скелет коду:
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();
Ось приклад коду для стиснення Цілого каталогу (включаючи під-файли та підкаталоги), він використовує функцію дерева файлів прогулянки 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();
}
}
}
Щоб скористатися цим, просто зателефонуйте
ZipCompress.compress("target/directoryToCompress");
і ви отримаєте каталог zip-файлівToCompress.zip
Весняний контролер завантаження, замовляйте файли в каталозі і їх можна завантажити.
@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");
}
}
}
Ось як ви створюєте поштовий файл з вихідного файлу:
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);
}
Один файл:
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);
}
Кілька файлів:
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);
}
}
Ви повинні створити дві функції. По-перше, це writeToZipFile (), а друге - createZipfileForOutPut ...., а потім викликаємо createZipfileForOutPut ("ім'я файлу .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();
}
}
Якщо ви хочете розпакувати без програмного забезпечення, краще скористайтеся цим кодом. Інший код з файлами PDF надсилає помилку при ручному розпакуванні
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();
}
Оскільки мені знадобилося певний час, щоб це зрозуміти, я подумав, що було б корисно розмістити своє рішення за допомогою 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());
}
}
}
З огляду на , exportPath
і в queryResults
якості змінних String, наступний блок створює results.zip
файл під exportPath
і записує вміст queryResults
в results.txt
файл всередині блискавки.
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);
}
Використання Jeka https://jeka.dev JkPathTree, це досить просто.
Path wholeDirToZip = Paths.get("dir/to/zip");
Path zipFile = Paths.get("file.zip");
JkPathTree.of(wholeDirToZip).zipTo(zipFile);
Існує ще один варіант, використовуючи zip4j
при https://github.com/srikanth-lingala/zip4j
Створення zip-файлу з одним файлом у ньому / Додавання одного файлу до наявного zip
new ZipFile("filename.zip").addFile("filename.ext");
Або
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Створення zip-файлу з декількома файлами / Додавання декількох файлів до наявного zip
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Створення zip-файлу шляхом додавання до нього папки / Додавання папки до існуючого zip
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Створення zip-файлу з потоку / Додавання потоку до існуючого поштового індексу
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);
в цей зразок коду включені два рядки ? Яке їх призначення?