not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

yogeshrai
M trying to use extra field support in apache.commons.compress.archivers version 1.5.Some how its not getting set since m not able to view it in hex editor and even after extracting using default ubuntu archive manager,last modified time is still set as server current timestamp ,even if i hv passed old date for testing.Kindly suggest.

Here's a standalone test class used to stimulate the use case.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.UnicodePathExtraField;
import org.apache.commons.compress.archivers.zip.X5455_ExtendedTimestamp;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipLong;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;

class X5455ExtendedTimestampTestClass {

    public static void main(String args[]) {
        X5455ExtendedTimestampTestClass.compressFolder("/home/yogeshrai/testdir", "/home/yogeshrai/testdir/testzip");
    }

    public static void compressFolder(String sourceFolder, String absoluteZipfilepath) {
        try {
            File srcFolder = new File(sourceFolder);
            if (srcFolder != null && srcFolder.isDirectory()) {
                Iterator < File > i = FileUtils.iterateFiles(srcFolder, null, true);
                File zipFile = new File(absoluteZipfilepath);
                zipFile.createNewFile();
                OutputStream outputStream = new FileOutputStream(zipFile);
                ArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(outputStream);
                int srcFolderLength = srcFolder.getAbsolutePath().length() + 1; // +1 to remove the last file separator
                while (i.hasNext()) {
                    File file = i.next();
                    String relativePath = file.getAbsolutePath().substring(srcFolderLength);
                    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath);
                    //add extended timestamp extra field for zip archive entry
                    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                    cal.set(Calendar.YEAR, 2000);
                    cal.set(Calendar.MONTH, Calendar.JANUARY);
                    cal.set(Calendar.DATE, 1);
                    cal.set(Calendar.HOUR_OF_DAY, 0);
                    cal.set(Calendar.MINUTE, 0);
                    cal.set(Calendar.MILLISECOND, 0);
                    Date timeMillis = cal.getTime();
                    X5455_ExtendedTimestamp xf = new X5455_ExtendedTimestamp();
                    ZipLong time = new ZipLong(timeMillis.getTime() / 1000);
                    xf.setModifyTime(time);
                    zipArchiveEntry.addExtraField(xf);
                    zipOutputStream.putArchiveEntry(zipArchiveEntry);
                    FileInputStream fis = null;
                    try {
                        fis = new FileInputStream(file);
                        IOUtils.copy(fis, zipOutputStream);
                    } finally {
                        fis.close();
                        zipOutputStream.closeArchiveEntry();
                    }
                }
                zipOutputStream.finish();
                zipOutputStream.close();
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: [compress] not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

Stefan Bodewig
On 2013-11-02, yogeshrai wrote:

> M trying to use extra field support in apache.commons.compress.archivers
> version 1.5.Some how its not getting set since m not able to view it in hex
> editor and even after extracting using default ubuntu archive manager,last
> modified time is still set as server current timestamp ,even if i hv passed
> old date for testing.Kindly suggest.

I've just re-read the code of X5455_ExtendedTimestamp and its API is a
bit inconvenient for people creating the extra data.  It is really more
geared towards reading the extra fields.

In order to add a timestamp you not only set the corresponding
Time-fields, you must also set a flag indicating the time is actualy
present.  In your case you are missing

                     xf.setFlags(1);

2 for access time and 4 for create time added together - see javadocs
of the setFlags method.  This is a bit inconvenient and I'll simplify
the API in trunk soonish.

BTW you could use setModifyJavaTime rather than setModifyTime to
simplify your code a little.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [compress] not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

Stefan Bodewig
On 2013-11-03, Stefan Bodewig wrote:

> This is a bit inconvenient and I'll simplify the API in trunk soonish.

https://issues.apache.org/jira/browse/COMPRESS-242

It would be good if you could verify that explicitly setting the flags
field fixes your problem.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [compress] not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

yogeshrai
Thnx a lot Stefan for prompt reply.I did made necessary change as suggested by u.Still even when i set all 3 date types to old date and then try to extract via default archive manager , m stuck with current date time for individual files bundled in.

M i missing anything more here.M using ubuntu 12.0X as test machine here.common compress 1.6 jar in use.


Here's update test class.

class EOSUnixSystemCall
{
        public static void main (String args[])  {
                EOSUnixSystemCall.compressFolder("/home/yogeshrai/testdir", "/home/yogeshrai/testdir/testzip");
   
    }
        public static void compressFolder(String sourceFolder, String absoluteZipfilepath)
    {
    try
    {
            File srcFolder = new File(sourceFolder);
            if(srcFolder != null && srcFolder.isDirectory())
                    {
            Iterator<File> i = FileUtils.iterateFiles(srcFolder,null, true);
                       

            File zipFile = new File(absoluteZipfilepath);
            zipFile.createNewFile();
            OutputStream outputStream = new FileOutputStream(zipFile);
            ArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(outputStream);
            int srcFolderLength = srcFolder.getAbsolutePath().length() + 1;  // +1 to remove the last file separator
            while(i.hasNext())
            {
            File file = i.next();
                    String relativePath  = file.getAbsolutePath().substring(srcFolderLength);
                    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath);
           
            //add extended timestamp extra field for zip archive entry
                                        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                                        cal.set(Calendar.YEAR, 1998);
                                        cal.set(Calendar.MONTH, Calendar.JANUARY);
                                        cal.set(Calendar.DATE, 1);
                                        cal.set(Calendar.HOUR_OF_DAY, 0);
                                        cal.set(Calendar.MINUTE, 0);
                                        cal.set(Calendar.MILLISECOND, 0);
                                        Date timeMillis = cal.getTime();
                                        X5455_ExtendedTimestamp xf = new X5455_ExtendedTimestamp();
                                        xf.setModifyJavaTime(timeMillis);
                                        xf.setCreateJavaTime(timeMillis);
                                        xf.setAccessJavaTime(timeMillis);
                                        xf.setFlags((byte) 4);
                                        zipArchiveEntry.addExtraField(xf);
                                        zipOutputStream.putArchiveEntry(zipArchiveEntry);
            FileInputStream fis = null;
                   try {
                                      fis = new FileInputStream(file);
                                      IOUtils.copy(fis , zipOutputStream);
                      }finally {
                                                  fis.close();
                                                  zipOutputStream.closeArchiveEntry();
                                    }    
            }
            zipOutputStream.finish();
            zipOutputStream.close();
            outputStream.close();
                    }
    }catch (Exception e) {
    e.printStackTrace();
                }
   
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: [compress] not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

Stefan Bodewig
On 2013-11-03, yogeshrai wrote:

> Thnx a lot Stefan for prompt reply.I did made necessary change as suggested
> by u.Still even when i set all 3 date types to old date and then try to
> extract via default archive manager , m stuck with current date time for
> individual files bundled in.

I may have been a bit unclear on setFlags, here is the rub:

> xf.setFlags((byte) 4);

this only sets the flag for the creation time, what you expect to see is
the modification time.

The flags is 1 for modification time plus 2 for access time plus 4 for
creation time.  So it should be 7 in your case.

For this I've created a new unit test with
<http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestampTest.java?r1=1538560&r2=1538559&pathrev=1538560>
and if I use InfoZIP's unzip on the created archive the resulting last
modified time is the one I set for the extra field.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [compress] not able to set extra field ExtendedTimestamp using commons.compress.archivers.zip

yogeshrai
Thnx a lot Stefan for clarification.Its working fine now as per expectations.