I am trying to write a spring boot java code to compress a Directory using REST API call. I find many codes using plain Java, but I am unable to find a one in Spring boot Java. I tried the below code and its zipping the file but when i try to zip the directory it throws FilenotFound Exception. Could anyone please help me with a working code. I dont know where I am going wrong. I am a beginner to Spring boot.
#RequestMapping(value="/zip", produces="application/zip")
public void zipFiles(HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.addHeader("Content-Disposition", "attachment; filename=\"compressedfile.zip\"");
ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
ArrayList<File> files = new ArrayList<>();
files.add(new File("C:\\Pavan\\zipfolder")); //(zip is working if(C:\\Pavan\\zipfolder\\dockerfile.txt)
for (File file : files) {
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
}
zipOutputStream.close();
}
Error:
You are passing a directory to the FileInputStream constructor. This is not allowed, see Javadoc. Instead you have to iterate over the files contained in this directory. See Zipping and Unzipping in Java for an example.
Related
To begin with, I am well aware that a similar topic is available on Stack OverFlow, but this one does not answer my problem. That's why I'm making this post.
At the moment, my program is able to search for ".csv" files locally, according to certain criteria, to add them to a list, and then to create a file in ".zip" format, which contains all these files. This works without any problem.
Now, I want to download this ".zip" file, from a Web interface, with a button. The connection between the code and the button works, but when I open my downloaded ".zip" file, it contains only one file, and not all the ".csv" files it is supposed to contain. Where can the problem come from?
Here is my code:
FileOutputStream baos = new FileOutputStream("myZip.zip");
ZipOutputStream zos = new ZipOutputStream(baos);
for(String sCurrent : selectedFiles){
zos.putNextEntry(new ZipEntry(new File(sCurrent).getName()));
Files.copy(Paths.get(sCurrent), zos);
zos.closeEntry();
}
zos.close();
response.getOutputStream().flush();
response.getOutputStream().close();
You are closing the ZIP after sending the response. Swap the order:
zos.close();
response.getOutputStream().write(baos.toByteArray());
It would be more efficient if you use try-with-resources to handle close, Files.copy(Paths.get(currentFile), zos); to transfer the files, and if you ZIP straight to the output stream because you might risk out of memory exceptions for large files:
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
Not an answer so much as consolidation based on #DuncG
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
for (String path : selectedFiles) {
zos.putNextEntry(new ZipEntry(new File(path).getName()));
Files.copy(Paths.get(path), zos);
zos.closeEntry();
}
zos.close();
In Java for a JUnit test, I am trying to mock a function that downloads a Zip File from another external API's endpoint. To simulate the download, I need to zip a test file and transform it into bytes to use as the mock's return value. I do not need to write the zipped file back to the file system but use the bytes raw as they are.
mock(zipReturner.getZipBytes()).thenReturn(testFileAsZippedBytes("testFile.txt"))
private Optional<byte[]> testFileAsZippedBytes(String testFile) {
???
}
Sharing my answer, because all the other examples I found are much heavier, require many more lines of code looping over bytes, or require using external libraries to do the same thing.
To do this without the above, use a combination of ByteArrayOutputStream, as it has the toByteArray function, ZipOutputStream to write zipped bytes to the ByteArrayOutputStream and FileInputStream to read the test file from the file system.
private Optional<byte[]> testFileAsZippedBytes(String filePath, String fileName) throws IOException {
try (
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
FileInputStream fileInputStream = new FileInputStream(filePath + fileName);
) {
ZipEntry zipEntry = new ZipEntry(fileName);
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(fileInputStream.readAllBytes());
zipOutputStream.finish();
return Optional.of(byteArrayOutputStream.toByteArray());
}
}
Use ZipEntry to add the file as an entry to the ZipOutputStream and write the bytes to the zip. Use zipOutputStream.finish() to ensure all contents are written to the stream and are ready to be consumed in the ByteArrayOutputStream, otherwise it was my experience that you would only get partial data when you call byteArrayOutputStream.toByteArray().
I know this question has been asked before, but I have a slightly different problem.
I want to read and write to a text file which will be included in my build(.jar file) . its a Gui application java.
Where Should I place the file?
I have placed the file by creating a new Resources folder under the project. This enables me to read the file but when I attempt to write to it, it throws a FileNotFound Exception. What should I do?
I am using this code
File file = new File(this.getClass().getClassLoader().getResource("score.txt").getFile());
FileOutputStream stream = new FileOutputStream(file);
DataOutputStream write = new DataOutputStream(stream);
write.writeInt(max);
And for Input i use this :
File file = new File(this.getClass().getClassLoader().getResource("Files/score.txt").getFile());
FileInputStream input = new FileInputStream(file);
DataInputStream read = new DataInputStream(input);
System.out.println(read.readInt());
For reading this code works perfectly.
I now have this problem. I want to write a excel file hold in this XSSFWorkbook (workbook) obj into a zip file eg(example.zip while contain this example.xlsx file) to a remote server.
I have tried following but not working, it created a folder with some odd files in the zip file
XSSFWorkbook workbook = new XSSFWorkbook();
//add some data
Zipoutputstream zipstream=new Zipoutputstream(//destination outputstream);
workbook.write(zipstream);
So do anyone knows what's the right way to do this? Thanks in advance
ps workbook.write(fileoutputstream) works but it only write to local disk as a flat file eg test.xlsx instead of inside a zip as I need.
Passing a a ZipOutputStream to XSSFWorkbook.write will result in the stream being hijacked and closed by the workbook. This is because an XSSFWorkbook writes a .xlsx which is itself a zip archive of xml and other files (you can unzip any .xslx to see what's in there).
If you're able to fit the excel file in memory, I've found this to work well:
ZipOutputStream zos = new ZipOutputStream(//destination outputstream);
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
bos.writeTo(zos);
zos.closeEntry();
// Add other entries as needed
zos.close();
Calling close on ByteArrayOutputStream has no effect and can still be written to zos.
You are missing some necessary calls on your ZipOutputStream. You will need to create a ZipEntry for your spreadsheet file, then write it out. You'll need something like
zipstream.putNextEntry(new ZipEntry("example.xlsx"));
Then you should be able to call
workbook.write(zipstream);
But after that you'll need to close the entry before closing the stream.
zipstream.closeEntry();
Please see "Write And Read .Zip File From Java" for details on how to use Java's ZipOutputStream.
Also, be aware that .xlsx files are already compressed zip files, so placing it in a .zip file may not compress it very much.
A colleague of mine, M. Bunshaft, suggested a solution similar to that of Klugscheißer but that does not require the use of a ByteArrayOutputStream, and hence can accommodate larger output.
The idea is to subclass ZipOutputStream, overriding the close() method so it will not do a close.
public class UncloseableZipOutputStream extends ZipOutputStream
{
OutputStream os;
public UncloseableZipOutputStream( OutputStream os )
{
super(os);
}
#Override
/** just flush but do not close */
public void close() throws IOException
{
flush();
}
public void reallyClose() throws IOException
{
super.close();
}
}
Then, simply use it the way you would use the ZipOutputStream.
UncloseableZipOutputStream zos = new UncloseableZipOutputStream(//destination outputstream);
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx"));
workbook.write(zos);
zos.closeEntry(); // now this will not cause a close of the stream
// Add other entries as needed
zos.reallyClose();
I'm coding a Spring MVC project on Eclipse. I'm stuck when coding the upload picture function. The client side using HTML5 API to read and send multipart file to server. The following code was used to save the image to server.
#RequestMapping(method = RequestMethod.POST)
public void processUpload(#RequestParam("pic") MultipartFile file) throws IOException {
// if (!result.hasErrors()) {
FileOutputStream outputStream = null;
String filePath = System.getProperty("java.io.tmpdir") + "/" + file.getOriginalFilename();
try {
outputStream = new FileOutputStream(new File(filePath));
outputStream.write(file.getInputStream().read());
outputStream.close();
} catch (Exception e) {
System.out.println("Error while saving file");
The file sent to server and get proceed but the file name is not original file name but some random string that java generated. I found that file in apache-tomcat-6.0.26\work\Catalina\localhost\ with name like this: upload__f20d9c4_1357767c999__7ffe_00000001. The file then disappear.
My question is where the file gone and how to correctly write uploaded file to some folder such as /uploads rather than save to temp folder?
I'm new hear so please correct me if I posted wrong :D
This might help :-
Change the file type to CommonsMultipartFile when you are fetching the file MultipartFile.
file.transferTo(new File("D:/"));
Let me know if this helps.
This may help as well :- http://www.codejava.net/frameworks/spring/spring-mvc-file-upload-tutorial-with-eclipse-ide