Win a copy of Programmers Guide to Apache Thrift this week in the Open Source forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Knute Snortum
  • Paul Clapham
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Ron McLeod
  • Piet Souris
  • Frits Walraven
Bartenders:
  • Ganesh Patekar
  • Tim Holloway
  • salvin francis

Generate3 csv files in zip format instead of individually  RSS feed

 
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I have this method in my springboot application which is generating 3 CSV files (related to Employee, Customer and Building) inside custom_users directory with timestamp appended to its name as shown below.






My questions:

Is it possible to zip these three files and then upload it inside custom_users folder? So, instead of 3 files I'll have a zip file , maybe with a name like this files_unixtimestamp.zip.
What changes I should be doing? Should I use servlet here to upload the files to the server in zip format or modify the existing code? Please advise. Thanks !

The reason I want to achieve this is :

1) I am using servlet from the client side to download these files in zip format. And since I could only download one file at a time using one servlet call, my call to the servlet would look something like this :

https://myservername.com/DownloadFileFromServer/DownloadFileServlet?filename=building_custom_file_112345786.csv

So, once I've zip related thing implemented , my call would look like the following:

https://myservername.com/DownloadFileFromServer/DownloadFileServlet?filename=files_112345786.zip


2) I won't have to append timestamp in front of the name of each of the 3 csv files.







 
Sheriff
Posts: 21741
102
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Check out ZipOutputStream. In short:
* Create a ZipOutputStream wrapped around a FileOutputStream.
* For each file:
   * Create a ZipEntry.
   * Call putNextEntry.
   * Write content to the ZipOutputStream. Don't close it!
   * Call closeEntry.
* Close the ZipOutputStream.

That "Don't close it!" can be troublesome, because it means you can't use try-with-resources, or perform any other finalization that a wrapping OutputStream may need. A simple workaround is to create a wrapper that does nothing for its close method. You can extend FilterOutputStream and override close to do nothing, or you can use commons-io's CloseShieldOutputStream.
 
Jack Tauson
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:Check out ZipOutputStream. In short:
* Create a ZipOutputStream wrapped around a FileOutputStream.
* For each file:
   * Create a ZipEntry.
   * Call putNextEntry.
   * Write content to the ZipOutputStream. Don't close it!
   * Call closeEntry.
* Close the ZipOutputStream.

That "Don't close it!" can be troublesome, because it means you can't use try-with-resources, or perform any other finalization that a wrapping OutputStream may need. A simple workaround is to create a wrapper that does nothing for its close method. You can extend FilterOutputStream and override close to do nothing, or you can use commons-io's CloseShieldOutputStream.



Thanks. I'm little bit confused as to whether I should let my current code generate the csv files inside a directory as it is currently doing OR should it directly go into the zip archive (this makes more sense to me). If latter is true, then, at what point and how should I get the file content without getting it saved in the directory in RHEL server?

Also, how FileOutputStream could help here? I'm little bit confused. Could you give some pseudo code related guidance based on my code? Thanks!
 
Marshal
Posts: 24458
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Short answer: the CSV data should go directly into the ZIP archive as ZipEntry objects. The FileOutputStream allows the ZIP archive to be written out to the file system as a file.
 
Paul Clapham
Marshal
Posts: 24458
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jack Tauson wrote:f latter is true, then, at what point and how should I get the file content without getting it saved in the directory in RHEL server?



But I don't understand this question at all. Your question is about how to generate a ZIP archive which contains three CSV files. Okay. Then all of a sudden there's a RHEL server and you want to get some file content from somewhere?
 
Jack Tauson
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Jack Tauson wrote:f latter is true, then, at what point and how should I get the file content without getting it saved in the directory in RHEL server?



But I don't understand this question at all. Your question is about how to generate a ZIP archive which contains three CSV files. Okay. Then all of a sudden there's a RHEL server and you want to get some file content from somewhere?



I believe that's my wrong imagination.  Whatever you mentioned above, "the CSV data should go directly into the ZIP archive as ZipEntry objects" is what I'm looking for. I mean, the zip file should exist inside the folder of RHEL server.
 
Jack Tauson
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Short answer: the CSV data should go directly into the ZIP archive as ZipEntry objects. The FileOutputStream allows the ZIP archive to be written out to the file system as a file.




So, I am trying to modify the CSVWriter's constructor in sucn a way that the CSV data should go directly into the ZIP archive as ZipEntry objects.

So I made the changes in the above code (visible after this line ResultSetMetaData rsmd = rsDemo.getMetaData(); in the code below). Right now I am just trying to put one file into ZIP archive to test but I noticed following errors:

Error on Line #173 says: The constructor ZipEntry(Path) is undefined.

Error on Line #175 says: Multiple markers at this line (one out of 2 errors is The constructor CSVWriter(ZipOutputStream) is undefined) .

Screenshot from my eclipse below:



Modified Code below:

 
Rob Spoor
Sheriff
Posts: 21741
102
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ZipEntry takes a String (or another ZipEntry, but let's ignore that), not a Path. You need to convert your Path to a String. For instance, to include the full path:

It's also possible you only want the file name:


As for the CSVWriter, this takes a Writer, not an OutputStream. You need to wrap it:

However, I will repeat my previous warning:

Rob Spoor wrote:Check out ZipOutputStream. In short:
   * Write content to the ZipOutputStream. Don't close it!


Closing the CSVWriter will close its nested OutputStreamWriter which will close its nested ZipOutputStream. As a result you can't write your second or third file anymore.
 
Jack Tauson
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:ZipEntry takes a String (or another ZipEntry, but let's ignore that), not a Path. You need to convert your Path to a String. For instance, to include the full path:

It's also possible you only want the file name:


As for the CSVWriter, this takes a Writer, not an OutputStream. You need to wrap it:

However, I will repeat my previous warning:

Rob Spoor wrote:Check out ZipOutputStream. In short:
   * Write content to the ZipOutputStream. Don't close it!


Closing the CSVWriter will close its nested OutputStreamWriter which will close its nested ZipOutputStream. As a result you can't write your second or third file anymore.



So, I made the following changes:



And I don't see zip file getting generated over there. What could be the reason? Other two files are getting generated in CSV format since I haven't made changes related to Zip conversion over there.
 
Rob Spoor
Sheriff
Posts: 21741
102
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jack Tauson wrote:


That creates the actual zip file, and it puts it in "the current working directory". Why don't you use the dir variable here? Files has method newOutputStream that you can use just like the newBufferedWriter method.
 
Jack Tauson
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:

Jack Tauson wrote:


That creates the actual zip file, and it puts it in "the current working directory". Why don't you use the dir variable here? Files has method newOutputStream that you can use just like the newBufferedWriter method.



Ah,I see. Looks like it wasn't able to find where to create a zip file.

You mean something like this?

Path dir = Paths.get("/srv/custom_users", userName);
Files.createDirectories(dir);

FileOutputStream fos = new FileOutputStream(Files.newOutputStream(dir));
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);



I am wondering how would I define the name of the zip file here? I mean previously, I had "your_files.zip" and now it has been replaced with Files.newOutputStream(dir)?

Also, I defined dir variable before FileOutputStream as I am using dir variable below.


               
               
 
Jack Tauson
Ranch Hand
Posts: 121
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote: Files has method newOutputStream that you can use just like the newBufferedWriter method.



So, I didn't have to use FileOutputStream at all. The following worked for me:




Thanks Rob and others for your valuable inputs. Appreciated!
 
Rob Spoor
Sheriff
Posts: 21741
102
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're welcome.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!