2014-10-23 3 views
1

I가 완봉 및 압축 해제를 위해 잘 작동하는이 :자바, 같은

public static final String SLASH = "/"; 
    public static void zip(int level, File zipfile, File... files) throws IOException { 
      try (FileOutputStream fo = new FileOutputStream(zipfile); ZipOutputStream zo = new ZipOutputStream(fo)) { 
        zo.setLevel(level); 

        for (File file : files) { 
          zip("", file, zo); 
        } 

        zo.flush(); 
        zo.finish(); 
        zo.close(); 

        // !!!!!!!! Tried these !!!!!!!!! 
        long time = Cal.date(1970, Cal.Month.JANUARY, 1).getTime(); 
        zipfile.setLastModified(time); 
        Files.setAttribute(zipfile.toPath(), "lastAccessTime", FileTime.fromMillis(time)); 
      } 
    } 

    public static File unzip(File zipfile, File to) throws IOException { 
      ZipFile       filezipped = new ZipFile(zipfile); 
      Enumeration<? extends ZipEntry> entries = filezipped.entries() ; 

      while (entries.hasMoreElements()) { 

        ZipEntry zipEntry = entries.nextElement()    ; 
        File  file  = new File(to, zipEntry.getName()); 

        if (zipEntry.isDirectory()) { 
          file.mkdirs(); 
        } 
        else { 
          file.getParentFile().mkdirs(); 
          try (InputStream in = filezipped.getInputStream(zipEntry)) { 
            Files.copy(in, file.toPath()); 
          } 
        } 
      } 

      return zipfile; 
    } 

    private static void zip(String base, File file, ZipOutputStream zo) throws IOException { 
      String path = base + file.getName(); 
      if (file.isDirectory()) { 
        path += SLASH; 

        zo.putNextEntry(new ZipEntry(path)); 

        for (File ff : file.listFiles()) { 
          zip(path, ff, zo); 
        } 

        zo.closeEntry(); 

      } else { 
        zo.putNextEntry(new ZipEntry(path)); 

        Files.copy(file.toPath(), zo); 

        zo.closeEntry(); 
      } 
    } 

그러나, zip 파일도의 내용하지만 다른 검사를해야합니다 파일은 변경되지 않습니다. git을 사용하여 파일을 커밋 할 때 문제가됩니다.

내용이 변경하지 않는 한 어떻게 압축 파일이 동일한 모든 시간을 유지하도록 할 수 있습니다?

+0

는 압축에있는 파일의 타임 스탬프에이 변경 있습니까? –

+0

흠, 아니요. 그러나 그것은 내가 압축 해제에 관해 생각하게했다. 압축이 풀린 후 다시 압축됩니다. 아마도 압축을 풀면 헤더 불일치가 발생합니다. 나는 시도 할 것이다. – momomo

+0

@RobbyCornelissen 아니, 내 대답은 아래에서와 같이'ZipEntry' 객체의 시간을 설정할 때 여전히 심지어 다른 MD5 – momomo

답변

2

자체가 문제가되지해야 ZIP 파일의 타임 스탬프하지만, 상수 값으로 ZIP 항목의 최종 수정 시간을 설정하십시오 :

ZipEntry entry = new ZipEntry(path); 
entry.setTime(0); 

zo.putNextEntry(entry); 

이 더 많은 정보를 위해 setTime의 JavaDoc을 참조하십시오.


업데이트

은 위의 사실 트릭을 할해야합니다, 당신의 항목의 내용과 순서를 동일하게 제공한다. 나는 ZipOutputStream에 대한 소스 코드를 살펴 가져다하여 putNextEntry 방법에 다음과 발견 :

if (e.time == -1) { 
    e.setTime(System.currentTimeMillis()); 
} 

그래서 덮어 쓰기되지 않도록해야 스트림에 항목을 추가하기 전에 0으로 time 설정을하고 계속 내용 상수.

+0

신난다, 너는 남자 야! zipEntry.setCreationTime, setLastAccessTime 및 setAccessTime도 있습니다. 나는 그것들을 사용하지 않았지만 setTime (0) 만 사용했다. – momomo

1

귀하의 Cal 클래스가 무엇을하는지 확신 할 수 없지만 내부적으로 Calendar 인스턴스를 만들고 날짜 필드를 설정하는 것으로 의심됩니다. 이 작업을 수행하면 여전히 00:00이 아니라 현재 시간으로 끝납니다. 그래서 당신은 대부분의 하지 것 같은 타임 스탬프 각 시간을 받고 있습니다.

난 그냥 오히려 일정 인스턴스에 대한 일 처리보다

long time = 0; 

을 시도 할 것입니다.

+0

저는 Calendar.getInstance(). get (year, month, day)를 사용합니다. 나는 이것이 괜찮다고 믿는다. Robbys 대답은 그 트릭을하는 것처럼 보였다. – momomo

+0

@SecretService 당신이 그것을 분류했기 때문에 기쁘다. '.set'을 의미합니까? 그것은 def OK가 아닙니다 : 그것은 당신이 선택한 날짜를 반환 할 것이지만 * 현재 시간입니다. 먼저 .clear()가 필요합니다. –

+0

네, 까다로운 사업입니다. 내가하고있는 cal.get (int, int, int); 나는 이것이 오늘의 시작을 돌려 준다고 믿는다. http://stackoverflow.com/questions/2445962/is-there-an-easier-way-to-get-start-of-current-day-time-than-this – momomo