我想將一些壓縮數據放入遠程存儲庫。
要將數據放在此存儲庫上,我只能使用一種方法,將資源及其內容的名稱作爲字符串。 (如data.txt +「hello world」)。
存儲庫正在調用文件系統,但沒有,所以我不能直接使用File。java:如何獲取壓縮字節數組的字符串表示形式?
我希望能夠做到以下幾點:
- 客戶端發送到服務器上的文件「data.txt中」
- 服務器壓縮「的data.txt」到壓縮文件「data.zip」
- 服務器發送的data.zip字符串表示到存儲庫
- 庫店data.zip 從倉庫data.zip
- 客戶端下載和他能夠與它喜歡的壓縮工具打開它
問題出現在步驟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
}
}
我同意。傳遞二進制數據時,您必須使用字節,而不是字符或字符串,它們是UTF16。 – 2010-05-19 16:59:18
@Marcus你的意思是UTF-8(檢查sys道具)。 爲了進行這項工作,您需要將整個文件的內容作爲字節數組加載,然後再將其轉換爲字符串。無論何時對字符串進行字節編碼/解碼,如果使用緩衝區,字符(可能跨越多個字節)可能會被錯誤地編碼/解碼。 – 2010-05-19 19:47:59
@雷蒙德,謝謝。我可能不清楚。字符串和字符是UTF16(多字節)。字節顯然是單字節,這就是你想要的。 – 2010-05-19 22:29:04