logo

Zip Up and Save Space

When you have a database which stores a lot of unzipped attachments, wouldn't it be nice if you could have an agent which periodically runs over them and zips them all? Sure could save a lot of space.

Well, you can and it's not even that difficult. The nice thing is you don't even need Winzip or any other tools to do it, it's already built into the Domino server and client! The magic word is "Java". Java has built in classes for zipping and unzipping files, which we are going to use for this small agent. There is just one small caveat: it only runs on R5.03 servers and above.

First, some things you need to make sure you have so as to get this example up and running:

Create a database, and in that database create a form. Call it whatever you want. On the form, create a rich text field called "Body" (you can call it something else, but then you'll have to modify the agent code below). Also create a view that shows these documents. Now create an agent which should run manually from the actions menu on selected documents.

Copy and paste the code below in to the agent. Don't get scared if it doesn't make a whole lot of sense. There are plenty of comments in the .Java file you can download here - ZipUp.java


// Written by Erwin van Hunen
//
// In this example the agent is run manually from the actions menu on selected documents,
// but of course it would make much more sense to run it as a scheduled or triggered agent
// in the background

import lotus.domino.*;
import java.io.*;
import java.util.*;
import java.util.zip.*;

public class JavaAgent extends AgentBase {

public void NotesMain() {

try {
FileOutputStream fos;
Item item;
RichTextItem rtitem;
String attachmentname;
Vector items;
String archivename;
byte b[] = new byte[512];

Session session = getSession();
AgentContext agentContext = session.getAgentContext();
Database db = agentContext.getCurrentDatabase();

DocumentCollection col = agentContext.getUnprocessedDocuments();

Document doc = col.getFirstDocument();
while (doc != null)
{
archivename = session.getEnvironmentString("Directory",true) + "\\" + doc.getNoteID() + ".zip";

fos = new FileOutputStream(archivename);

ZipOutputStream zout = new ZipOutputStream(fos);

rtitem = (RichTextItem) doc.getFirstItem("Body");

items = doc.getItems();
for (int i=0; i<items.size(); i++) {
item = (Item) items.elementAt(i);
if(item.getType() == Item.ATTACHMENT)
{
if (item.getValueString().length() != 0)
{
attachmentname = item.getValueString();

EmbeddedObject attachment = (EmbeddedObject) doc.getAttachment(attachmentname);

InputStream in = attachment.getInputStream();

ZipEntry e = new ZipEntry(attachment.getName().replace(File.separatorChar,'/'));

zout.putNextEntry(e);
int len=0;

while((len=in.read(b)) != -1)
{
zout.write(b,0,len);
}
zout.closeEntry();
attachment.remove();
}
}
}
zout.close();
fos.close();
doc.replaceItemValue("Body","");
rtitem.embedObject(EmbeddedObject.EMBED_ATTACHMENT, null, archivename, archivename);

doc.save(true);

File zipfile = new File(archivename);
zipfile.delete();

doc = col.getNextDocument(doc);
}

} catch (Exception e) {
e.printStackTrace();
}

}
}

Trying the agent:

Create a document in the database and attach some files in the body field. Save the document, close it, select it in the view and run the agent from the actions menu. When the agent finishes, open the document and you should see a zip file instead of your attachments.

Basically this is what happens when you run the agent:

Domino creates an empty zipfile in the Notes\Data directory which is named after the NoteID of the document. Then it loops through all the attachments on the document and add them to the zipfile. Finally, it deletes the attachments from the document and attaches the zipfile to the document.

I can think of a lot of improvements, like setting a flag which means that the attachments already have been zipped, having a user editable field for the zipfilename, or using the date for the zipfilename, or what about an online zipper? Just provide the user with a form on which he can upload a file, have an agent zip the attachment and present the zipped file?

All in all very straightforward I would say! No need for external libraries, tools, etc. It's all done with built-in functionality of the Domino server and the Notes client. Isn't this the reason why we all love Domino?

Jake's Comments:

Thanks Erwin. Great write up.

You may all have noticed that this isn't really a Domino based solution. When we have a web based application the attachments are rarely in the Body field. This is not to say that it can't be made in to one though, as Erwin mentions. The reason I decided to publish Erwin's article is that it is such good food for thought.

I've placed the code in a file you can download from the top left of the page, to make life easier.

About the Author:

Erwin van Hunen is from The Netherlands and currently works as a Lotus Domino Application Architect for Inter Access B.V.

Feedback

    • avatar
    • Brendon
    • Sat 17 Nov 2001

    Confused

    Hmm...

    Doesn't Notes have a compression function? Why would I do this?

      • avatar
      • Erwin van Hunen
      • Mon 19 Nov 2001

      Re: Confused

      Actually I can come up with at least one reason: say you want to give users the option to upload a set of word documents, which should be made available as a zip file for download.

      This agent can make the zip file without bothering the uploader to create the zip file etc. etc.

      Show the rest of this thread

      • avatar
      • Fabrice P
      • Wed 21 Nov 2001

      Re: Confused

      The compression function of Notes when you attach a file is quite ineficiente.

      Compare when you attach a file with compression active, without compression, to the size of the file if zipped and you'll see from yourself.

      FP (France)

    1. Saves bandwidth...

      When Domino serves up a Domino-compressed attachment, it first decompresses it, then sends it over the wire. But a zip file stays compressed, making for a smaller download.

      The user saves download time, you save money on bandwidth. Everyone's happy!

      Sean

  1. How can I remove the icon

    Hi

    I found the code very usefull but I don't like the deletion of the content of the body field. So I remove that part. But unfortunately, the attachment icon is (although the attachment has been removed) still visible. What can I do to remove the icon?

    Regards Chris

      • avatar
      • Erwin van Hunen
      • Sun 27 Jan 2002

      Re: How can I remove the icon

      That was exactly my problem, which is the only reason I remove the contents of the body field...

      Show the rest of this thread

    • avatar
    • Adam Gadsby
    • Tue 12 Nov 2002

    Cannot View Files

    Although this works very well to ZIP files, if you click on the attached ZIP file and choose view, you cannot preview the files within the ZIP file. It displays the following error: "Sorry, the program encountered a problem and cannot view the document"

    Normally, you can do this.

    Any ideas?

      • avatar
      • Mr X
      • Fri 31 Jan 2003

      Re: Cannot View Files

      I've test this on a R5 client and an N6 client. The R5 client viewer worked fine. The N6 client gave the error you describe. Didn't find anything in the fixlist for this, but will call support, because this definitely looks like a useful tool.

      Show the rest of this thread

      • avatar
      • Timo
      • Mon 17 Mar 2003

      Re: Cannot View Files

      Hi, did you find a solution? Still using that agent? I would like to share your experiences with that tool.

    • avatar
    • Albina
    • Tue 15 Jul 2003

    Zipping an attachment while sending a mail

    Hi,

    Can this feature be used in Lotus Script also?

    I am trying to send a mail with zipped attachment to save space in recipient's mail box.

    TIA, Albina

  2. can you make this work on domino?

    As Jake said, this isn't really a domino solution since the attachments aren't in the body field. Can you make this work on a domino db where the attachments are uploaded via file upload control?

    What is the difference between this and the other product mentioned - zipmail?

    Thanks!!! :-)

  3. <> What about the other way?

    Has anyone got any examples of taking a zip file and automatically unzipping it?

    Is there any help available on these methods?

    TIA

    Malc.

    1. Re: <> What about the other way?

      hey malc, I am also facing the same problem.have u got any solution for unzipping the zipped attachments.

      Thanks in Advance Ashish Kr.Srivastava

      Show the rest of this thread

  4. Problem with Zipping the content of directory and

    hello i m nikhil. i m trying to zip the contents of directory and the file which are in the sub directory .i have used java.util.zip. Programmes run without any error but when i open the newly zip file it only list the contents of files in the directory but programmes doesnt zip the subdirectory

    thnks nikhil below there is a code import java.util.*; import java.io.*; import java.util.zip.*; class DirTest { public void filePath(String strFilename) { String s[]=new String[0]; ArrayList arr=new ArrayList(); try { File f=new File(strFilename); if(f.isDirectory()) { s=f.list(); } for(int i=0;i<s.length;i++) { File f1=new File(f.getPath()+"/"+ s[i]); if(f1.isDirectory()) { filePath(f1.getPath()); } else { arr.add(f1.getPath()); } } arrListing(arr); } catch(Exception e) { System.out.println(e.getMessage()); } } public void arrListing(ArrayList a1) { try { FileOutputStream fout=new FileOutputStream("C:/myDir/ot.zip"); ZipOutputStream zout=new ZipOutputStream(fout); FileInputStream fin=null; Iterator itr=a1.iterator(); while(itr.hasNext()) { String str=(String) itr.next(); System.out.println(str); zout.setMethod(ZipOutputStream.DEFLATED); zout.setLevel(9); zout.putNextEntry(new ZipEntry(str)); fin=new FileInputStream(str); int c; while((c=fin.read())!=-1) { zout.write(c); } zout.flush(); }

    fin.close(); zout.closeEntry(); zout.close(); } catch(Exception e) { System.out.println(e); } } public static void main(String args[]) throws IOException { DirTest objDir=new DirTest(); objDir.filePath("C:/myDir"); } }

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:



Navigate other articles in the category "Java"

« Previous Article Next Article »
At last, an applet worth using   Multiple Threads in Notes Agents

About This Article

Author: Erwin van Hunen
Category: Java
Keywords: Zip; attachments; file; body;

Attachments

ZipUp.Java (4 Kbytes)

Options

Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »