commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Fortner <phidia...@gmail.com>
Subject Re: Windows XP Compressed Folders doesn't recognize my VFS-based zip file
Date Wed, 06 Jan 2010 00:00:49 GMT
Hi Stephen,

Thanks for posting this. I read your blog entry as well. You mention
in passing that POI doesn't support the new formats. There's a
separate module that is supposed to support xlsx and docx formats. I
was able to use them in the past. Was there some particular "gotcha"
that people should keep an eye out for?

Regards,

Mark

On Tuesday, January 5, 2010, Stephen Huey <stephen.huey@gmail.com> wrote:
> For posterity's sake, I meant to come back here and post the solution a
> while ago.  I've got the full story here in this blog post:
>
> http://stephenhuey.wordpress.com/2010/01/01/docxgae/
>
> The relatively new Microsoft Office formats ending with extensions such as
> .docx and .xlsx are zip files of directories of text files (XML) and images.
>  Tried-and-true Java libraries for writing the old binary Microsoft Word and
> Excel formats aren't yet supported on Google App Engine, so I was glad to
> get this working since it was a required feature for our application.
>
> My modified code for the zipDir and addDir methods is below.  As you can
> see, I'm closing the ZipOutputStream rather than the OutputStream:
>
>
> + + + + + + + + + + + + + + + + + + + +
>
>
> import java.io.BufferedInputStream;
> import java.io.IOException;
> import java.io.OutputStream;
> import java.util.zip.ZipEntry;
> import java.util.zip.ZipOutputStream;
>
> import org.apache.commons.vfs.FileObject;
> import org.apache.commons.vfs.FileSystemException;
> import org.apache.commons.vfs.FileSystemManager;
> import org.apache.commons.vfs.FileType;
>
> public class FileObjectHelper {
>
>  public static FileObject createFolder(FileSystemManager fsManager, String
> absolutePath) throws FileSystemException {
>  FileObject theFolder = fsManager.resolveFile( absolutePath );
>  if ( theFolder.exists() == false) {
>  theFolder.createFolder();
>  }
>  return theFolder;
>  }
>
>  public static FileObject createFile(FileSystemManager fsManager, String
> absolutePath) throws FileSystemException {
>  FileObject theFile = fsManager.resolveFile( absolutePath );
>  if ( theFile.exists() == false) {
>  theFile.createFile();
>  }
>  return theFile;
>  }
>
>  public static void zipDir(FileObject docxZipFile, FileObject
> directoryToZip) throws IOException {
>  OutputStream out = docxZipFile.getContent().getOutputStream();
>  ZipOutputStream zout = new ZipOutputStream(out);
>  addDir(directoryToZip, zout, "");
>  zout.close(); // make sure you close the ZipOutputStream, not the
> OutputStream!
>  }
>
>  public static void addDir(FileObject dirObj, ZipOutputStream zout, String
> basePathSoFar) throws IOException {
>  FileObject[] files = dirObj.getChildren();
>  byte[] tmpBuf = new byte[1024];
>
>  for (int i = 0; i < files.length; i++) {
>  FileObject currentFile = files[i];
>  String currentFileBaseName = currentFile.getName().getBaseName();
>
>  if (currentFile.getType().equals(FileType.FOLDER)) {
>  addDir(currentFile, zout, basePathSoFar + currentFileBaseName + "/");
>
>  } else { // else it's a file, not a directory
>  BufferedInputStream bis = new
> BufferedInputStream(currentFile.getContent().getInputStream());
>  zout.putNextEntry(new ZipEntry(basePathSoFar + currentFileBaseName));
>  int len;
>  while ((len = bis.read(tmpBuf)) != -1) {
>  zout.write(tmpBuf, 0, len);
>  }
>  zout.closeEntry();
>  bis.close();
>  } // end if
>  } // end for loop
>  } // end addDir
> }
>
>
> + + + + + + + + + + + + + + + + + + + +
>
>
>
>
>
> Happy New Year,
> Stephen Huey
>
>
>
>
> On Tue, Dec 15, 2009 at 1:54 AM, Stephen Huey <stephen.huey@gmail.com>wrote:
>
>> I'm using GaeVFS which is based on Commons VFS, and I feel that my question
>> is probably more relevant to Commons VFS than the Google App Engine layer on
>> top of it.  My goal is to construct valid zip files on Google App Engine,
>> and I successfully used GaeVFS to create zip files that Mac OS X can open
>> and that Winzip on Windows can open, but Windows XP Compressed Folders
>> refused to acknowledge files in subdirectories in the zip until I removed
>> the leading forward slash from a ZipEntry whose name began with a
>> directory.
>>
>> For example, the following basic class successfully generates a zip file
>> containing a file in a subdirectory that Windows XP Compressed Folders will
>> open:
>>
>>
>> import java.util.zip.*;
>> import java.io.*;
>> public class ZipThis {
>>   public static void main(String args[]) throws IOException {
>>     if (args.length < 1) {
>>       System.err.println("usage: java ZipThis Zip.zip");
>>       System.exit(-1);
>>     }
>>     File zipFile = new File(args[0]);
>>     if (zipFile.exists()) {
>>       System.err.println("Zip file already exists, please try another");
>>       System.exit(-2);
>>     }
>>     FileOutputStream fos = new FileOutputStream(zipFile);
>>     ZipOutputStream zos = new ZipOutputStream(fos);
>>     int bytesRead;
>>     String[] files = new String[] {"D:/stylessub/styles.xml",
>> "D:/document.xml"};
>>     String[] entryName = new String[] {"stylessub/styles.xml",
>> "document.xml"};
>>     byte[] buffer = new byte[1024];
>>     for (int i=0, n=files.length; i < n; i++) {
>>       String name = files[i];
>>       File file = new File(name);
>>       if (!file.exists()) {
>>         System.out.println("Skipping: " + name);
>>         continue;
>>       }
>>       BufferedInputStream bis = new BufferedInputStream(new
>> FileInputStream(file));
>>       ZipEntry entry = new ZipEntry(entryName[i]);
>>       zos.putNextEntry(entry);
>>       while ((bytesRead = bis.read(buffer)) != -1) {
>>         zos.write(buffer, 0, bytesRead);
>>       }
>>       bis.close();
>>       zos.closeEntry();
>>
>>     }
>>     zos.close();
>>   }
>> }
>>
>>
>> Now I'm trying to get my virtual file system code to generate a zip that
>> Windows won't complain about with this error message:  "The Compressed
>> (zipped) Folder is isvalid or corrupted."  I want to meet the Microsoft
>> employee who wrote that error message!  :)
>>
>> So here's some initial setup in my servlet:
>>
>> FileObject docxZipFile = FileObjectHelper.createFile(fsManager,
>> "gae://gaevfs/generatedZip/docxFile.zip");
>> FileObject docxRootFolder = FileObjectHelper.createFolder(fsManager,
>> "gae://gaevfs/docxDirectory");
>>
>> These helper methods are being used:
>>
>>     public static FileObject createFile(FileSystemManager fsManager, String
>> absolutePath) throws FileSystemException {
>>         FileObject theFile = fsManager.resolveFile( absolutePath );
>>         if ( theFile.exists() == false) {
>>             theFile.createFile();
>>         }
>>         return theFile;
>>     }
>>
>>     public static FileObject createFolder(FileSystemManager fsManager,
>> String absolutePath) throws FileSystemException {
>>         FileObject theFolder = fsManager.resolveFile( absolutePath );
>>         if ( theFolder.exists() == false) {
>>             theFolder.createFolder();
>>         }
>>         return theFolder;
>>     }
>>
>> Pardon the near redundancy.  Anyway, the next line begins the zipping:
>>
>> FileObjectHelper.zipDir(docxZipFile, d

-- 
Mark Fortner

blog: http://feeds.feedburner.com/jroller/ideafactory

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message