2011-08-15 35 views
1

我正在嘗試使用以下代碼從Internet解壓縮文件。在其中一個文件(「uq.class」)中,從聯機源解壓縮後,缺少約2kb的文件大小(原始文件爲10,084,解壓縮爲8,261)。所有其他文件似乎是完全正常的,當我從zip中複製uq.class文件並手動放置它時,它的功能完美無缺。任何人都可以解釋發生了什麼並提供修復?以下是代碼的解壓縮部分。Java從URL上解壓縮丟失文件上的2kb

public static File unpackArchive(URL url, File targetDir) throws IOException { 
    if (!targetDir.exists()) { 
     targetDir.mkdirs(); 
    } 
    InputStream in = new BufferedInputStream(url.openStream(), 2048); 
    // make sure we get the actual file 
    File zip = File.createTempFile("arc", ".zip", targetDir); 
    OutputStream out = new BufferedOutputStream(new FileOutputStream(zip),2048); 
    copyInputStream(in, out); 
    out.close(); 
    return unpackArchive(zip, targetDir); 
} 
public static File unpackArchive(File theFile, File targetDir) throws IOException { 
    if (!theFile.exists()) { 
     throw new IOException(theFile.getAbsolutePath() + " does not exist"); 
    } 
    if (!buildDirectory(targetDir)) { 
     throw new IOException("Could not create directory: " + targetDir); 
    } 
    ZipFile zipFile = new ZipFile(theFile); 
    for (Enumeration entries = zipFile.entries(); entries.hasMoreElements();) { 
     ZipEntry entry = (ZipEntry) entries.nextElement(); 
     File file = new File(targetDir, File.separator + entry.getName()); 
     if (!buildDirectory(file.getParentFile())) { 
      throw new IOException("Could not create directory: " + file.getParentFile()); 
     } 
     if (!entry.isDirectory()) { 
      copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(file),2048)); 
     } else { 
      if (!buildDirectory(file)) { 
       throw new IOException("Could not create directory: " + file); 
      } 
     } 
    } 
    zipFile.close(); 
    theFile.delete(); 
    return theFile; 
} 

public static void copyInputStream(InputStream in, OutputStream out) throws IOException { 
    byte[] buffer = new byte[1024]; 
    int len = in.read(buffer); 
    while (len >= 0) { 
     out.write(buffer, 0, len); 
     len = in.read(buffer); 
    } 
    in.close(); 
    out.close(); 
} 
public static boolean buildDirectory(File file) { 
    return file.exists() || file.mkdirs(); 
} 

回答

2

無法直接看到代碼乍一看有什麼問題。然而,我會推薦你​​做的是更安全地關閉你的流。在您當前的實現中,您同時關閉輸入輸出流,關閉語句會導致讀寫語句異常!如果其中任何一個失敗,您的文件將保持打開並及時應用程序將用完文件描述符。你最好在最後的陳述中結束,這樣你就可以確定他們會被關閉。

+0

此外,你關閉你的兩次流出;) – Dorpsidioot

0

我不知道爲什麼我無法登錄,但我找到了問題。我在馬前面做了整車。我提取了正確的文件,然後將舊文件提取出來,所以我不斷重新整合舊文件。在窗外編程5小時。請記住,小子,正確的編程架構可以爲您節省一大筆頭痛的問題。

+0

哈哈,這看起來像典型的週五下午編碼類型的問題;) – Dorpsidioot