2010-05-19 26 views
1

我想将一些压缩数据放入远程存储库。
要将数据放在此存储库上,我只能使用一种方法,将资源及其内容的名称作为字符串。 (如data.txt +“hello world”)。
存储库正在调用文件系统,但没有,所以我不能直接使用File。java:如何获取压缩字节数组的字符串表示形式?

我希望能够做到以下几点:

  1. 客户端发送到服务器上的文件“data.txt中”
  2. 服务器压缩“的data.txt”到压缩文件“data.zip”
  3. 服务器发送的data.zip字符串表示到存储库
  4. 库店data.zip
  5. 从仓库data.zip
  6. 客户端下载和他能够与它喜欢的压缩工具打开它

问题出现在步骤3当我尝试获取我的压缩文件的字符串表示形式。

下面是一个示例类,使用zip *流并模拟存储库展示我的问题。
创建的zip文件正在工作,但是在其“序列化”之后,它会被损坏。
(样品班使用雅加达commons.io)

非常感谢您的帮助。

package zip; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 
import java.util.zip.ZipOutputStream; 

import org.apache.commons.io.FileUtils; 

/** 
* Date: May 19, 2010 - 6:13:07 PM 
* 
* @author Guillaume AME. 
*/ 
public class ZipMe { 
    public static void addOrUpdate(File zipFile, File ... files) throws IOException { 

     File tempFile = File.createTempFile(zipFile.getName(), null); 
     // delete it, otherwise you cannot rename your existing zip to it. 
     tempFile.delete(); 

     boolean renameOk = zipFile.renameTo(tempFile); 
     if (!renameOk) { 
      throw new RuntimeException("could not rename the file " + zipFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath()); 
     } 
     byte[] buf = new byte[1024]; 

     ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile)); 
     ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile)); 

     ZipEntry entry = zin.getNextEntry(); 
     while (entry != null) { 
      String name = entry.getName(); 
      boolean notInFiles = true; 
      for (File f : files) { 
       if (f.getName().equals(name)) { 
        notInFiles = false; 
        break; 
       } 
      } 
      if (notInFiles) { 
       // Add ZIP entry to output stream. 
       out.putNextEntry(new ZipEntry(name)); 
       // Transfer bytes from the ZIP file to the output file 
       int len; 
       while ((len = zin.read(buf)) > 0) { 
        out.write(buf, 0, len); 
       } 
      } 
      entry = zin.getNextEntry(); 
     } 
     // Close the streams 
     zin.close(); 
     // Compress the files 
     if (files != null) { 
      for (File file : files) { 
       InputStream in = new FileInputStream(file); 
       // Add ZIP entry to output stream. 
       out.putNextEntry(new ZipEntry(file.getName())); 
       // Transfer bytes from the file to the ZIP file 
       int len; 
       while ((len = in.read(buf)) > 0) { 
        out.write(buf, 0, len); 
       } 
       // Complete the entry 
       out.closeEntry(); 
       in.close(); 
      } 
      // Complete the ZIP file 
     } 
     tempFile.delete(); 
     out.close(); 

    } 

    public static void main(String[] args) throws IOException { 

     final String zipArchivePath = "c:/temp/archive.zip"; 
     final String tempFilePath = "c:/temp/data.txt"; 
     final String resultZipFile = "c:/temp/resultingArchive.zip"; 

     File zipArchive = new File(zipArchivePath); 
     FileUtils.touch(zipArchive); 

     File tempFile = new File(tempFilePath); 
     FileUtils.writeStringToFile(tempFile, "hello world"); 
     addOrUpdate(zipArchive, tempFile); 

     //archive.zip exists and contains a compressed data.txt that can be read using winrar 

     //now simulate writing of the zip into a in memory cache 
     String archiveText = FileUtils.readFileToString(zipArchive); 
     FileUtils.writeStringToFile(new File(resultZipFile), archiveText); 

     //resultingArchive.zip exists, contains a compressed data.txt, but it can not 
     //be read using winrar: CRC failed in data.txt. The file is corrupt 

    } 

} 

回答

1

服务器发送 data.zip的字符串表示

所以,你要得到一个zip(即二进制)流的字符串(即文本)表示库。

Base64是最流行的方式来做到这一点。

一种流行的Java实现从Apache commonscodec成分)

2

Zip文件是二进制文件。 Java中的字符串处理是文本处理,可能会改变CRLF,零字节和EOF标记。当涉及到读取和重写zip文件时,我建议您尝试使用readFileToByteArraywriteByteArrayToFile作为实验。如果这样做,那么我会怀疑字符串处理是责任。

+0

我同意。传递二进制数据时,您必须使用字节,而不是字符或字符串,它们是UTF16。 – 2010-05-19 16:59:18

+0

@Marcus你的意思是UTF-8(检查sys道具)。 为了进行这项工作,您需要将整个文件的内容作为字节数组加载,然后再将其转换为字符串。无论何时对字符串进行字节编码/解码,如果使用缓冲区,字符(可能跨越多个字节)可能会被错误地编码/解码。 – 2010-05-19 19:47:59

+0

@雷蒙德,谢谢。我可能不清楚。字符串和字符是UTF16(多字节)。字节显然是单字节,这就是你想要的。 – 2010-05-19 22:29:04

相关问题