2010-05-19 67 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

相關問題