Jaki jest najlepszy sposób, aby się dowiedzieć, czy java.io.InputStream
zawiera spakowane dane?Najlepszy sposób na wykrycie, czy strumień jest spakowany w Javie
Odpowiedz
Numer magic bytes dla formatu ZIP to 50 4B
. Możesz przetestować strumień (używając mark i reset - możesz potrzebować do buffer), ale nie spodziewałbym się, że będzie to podejście w 100% niezawodne. Nie byłoby sposobu na odróżnienie go od pliku tekstowego zakodowanego w US-ASCII, który zaczynał się od liter PK
.
Jednym ze sposobów uzyskania metadanych w formacie treści przed otwarciem strumienia byłoby odpowiednie przetworzenie.
Nie bardzo elegancki, ale niezawodne:
Jeśli strumień można odczytać poprzez ZipInputStream
, to powinny być spakowane.
Można sprawdzić, że pierwsze cztery bajty strumienia są podpis lokalny nagłówek pliku który rozpoczyna nagłówek lokalnego pliku zachodzącej każdy plik w formacie ZIP, as shown in the spec here być 50 4B 03 04
.
Trochę kodu testu pokazuje to działa:
byte[] buffer = new byte[4];
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("so.zip"));
ZipEntry ze = new ZipEntry("HelloWorld.txt");
zos.putNextEntry(ze);
zos.write("Hello world".getBytes());
zos.close();
FileInputStream is = new FileInputStream("so.zip");
is.read(buffer);
is.close();
}
catch(IOException e) {
e.printStackTrace();
}
for (byte b : buffer) {
System.out.printf("%H ",b);
}
dał mi ten wynik:
50 4B 3 4
Miałem ten sam pomysł (chociaż zaufana Wikipedia ponad specyfikacją - wstyd!), Ale wygląda na to, że nie jest to niezawodny mechanizm: _ "Twórcy aplikacji powinni mieć świadomość, że można napotkać pliki ZIP z tymi deskryptorami danych oznaczania podpisów lub bez nich i powinien brać pod uwagę oba przypadki podczas czytania plików ZIP, aby zapewnić zgodność. "_ – McDowell
To prawda z ogólnej perspektywy, ale domyślam się, że jeśli nie masz podpisu ZipInputStream zawiedzie, ponieważ nalega na obiekty ZipEntry. –
Możesz mieć losowe śmieci dodawane do plików zip (takich jak pliki wykonywalne Microsoft Windows). Działają one tylko wtedy, gdy korzystasz z katalogu centralnego zamiast streamingu z lokalnymi nagłówkami. FWIW, Java PlugIn i WebStart korzystają z katalogu centralnego, ale teraz sprawdzają również pierwsze cztery bajty (patrz GIAR). –
Wprowadzenie
Ponieważ wszystkie odpowiedzi są 5 lat czuję się obowiązek spisać, co się dzisiaj dzieje. Poważnie wątpię, że należy czytać magiczne bajty strumienia! To kod niskiego poziomu, należy go ogólnie unikać.
Prosta odpowiedź
miku pisze:
Jeśli strumień można odczytać poprzez ZipInputStream należy spakowane.
Tak, ale w przypadku ZipInputStream
„można przeczytać” oznacza, że pierwsze wezwanie do .getNextEntry()
zwraca niezerową wartość. Bez wyjątku łapanie et cetera. Więc zamiast magicznych bajtów parsowania można po prostu zrobić:
boolean isZipped = new ZipInputStream(yourInputStream).getNextEntry() != null;
I to jest to!
ogólne rozpakować myśli
Ogólnie okazało się, że jest to o wiele bardziej wygodne do pracy z plikami podczas [un] skompresowanie, niż ze strumieni. Istnieje kilka przydatnych bibliotek, a ZipFile ma więcej funkcji niż ZipInputStream. Obsługa plików zip jest omówiona tutaj: What is a good Java library to zip/unzip files? Więc jeśli możesz pracować z plikami, lepiej!
przykładowy kod
potrzebowałem w mojej aplikacji do pracy z tylko strumieni. To jest ta metoda, którą napisałem do rozpakowania:
import org.apache.commons.io.IOUtils;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public boolean unzip(InputStream inputStream, File outputFolder) throws IOException {
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry entry;
boolean isEmpty = true;
while ((entry = zis.getNextEntry()) != null) {
isEmpty = false;
File newFile = new File(outputFolder, entry.getName());
if (newFile.getParentFile().mkdirs() && !entry.isDirectory()) {
FileOutputStream fos = new FileOutputStream(newFile);
IOUtils.copy(zis, fos);
IOUtils.closeQuietly(fos);
}
}
IOUtils.closeQuietly(zis);
return !isEmpty;
}
Istnieją sytuacje, w których 'ZipOutputStream' nie jest poprawnie ukończony lub zamknięty, co oznacza, że wynikowy plik wygeneruje' wyjątek IOEx', gdy zostanie sparsowany do 'nowego pliku ZipFile (f)', ponieważ jest niepoprawny. Powyższe nie zawiedzie, nawet jeśli plik zip jest nieprawidłowy do innych celów. –
Sprawdzanie magicznej liczby może nie być właściwą opcją.
plików DOCX mają również podobną liczbę magiczną 50 4B 3 4
To dlatego, że pliki docx są plikami zip. – tak3shi
- 1. Najlepszy sposób na wykrycie IronPython
- 2. Jaki jest najlepszy sposób na wykrycie obecności SMO?
- 3. Najlepszy sposób na wykrycie użytkowników mobilnych w Magento
- 4. Jaki jest najlepszy sposób na wykrycie, czy serwer proxy jest dostępny?
- 5. Najlepszy sposób na zmianę ArrayList w Javie
- 6. Najlepszy sposób na wykrycie typu sprzętu, iPhone4 lub iPhone5?
- 7. Jaki jest najlepszy sposób na oczyszczenie obiektu w Javie?
- 8. Najlepszy sposób na analizowanie Java w Javie
- 9. iPhone: Najlepszy sposób na wykrycie końca sekwencji animacji obrazów UIImageView
- 10. Najlepszy sposób na wykrycie kompilacji wydania z kompilacji debugowania? .net
- 11. Czy to właściwy sposób na wykrycie iPada?
- 12. Czy istnieje dobry sposób na wykrycie, że MySQL jest "gotowy"?
- 13. Czy istnieje sposób na wykrycie, czy apk został zaciemniony?
- 14. Jaki jest najlepszy sposób tworzenia struktur wiadomości w Javie?
- 15. Najlepszy sposób użycia zawiera ArrayList w Javie?
- 16. Jaki jest najlepszy sposób skalowania obrazów w Javie?
- 17. Najlepszy sposób na rozróżnienie ESTALE i ENOENT w Javie
- 18. Najlepszy sposób na utworzenie pustej mapy w Javie
- 19. najprostszy sposób na wykrycie, czy urządzenie mobilne z javascript
- 20. Szybki sposób na wykrycie, czy istnieje tabela lub widok DataContext
- 21. Sposób na wykrycie adresu URL przekierowania
- 22. Czy istnieje dobry sposób na wykrycie nieaktualnego mount NFS
- 23. Jaki jest najlepszy sposób na podstawowe rozpoznawanie liczb?
- 24. Czy jest jakiś strumień wiadomości (strumień wydarzeń/aktywności)?
- 25. Czy jest możliwe wykrycie przeglądarki Samsung zapasów
- 26. Najlepszy sposób na "zanegowanie" instancji
- 27. Elegancki sposób na wykrycie, czy aplikacja GWT jest nieaktualna i czy automatycznie odświeżana przeglądarka?
- 28. Właściwy sposób na zabicie procesu w Javie
- 29. Czy istnieje sposób sprawdzenia, czy zmienna jest zdefiniowana w Javie?
- 30. Jaki jest najłatwiejszy sposób na wykrycie, czy co najmniej jedno pole zostało zmienione w formularzu HTML?
Czy ta część żądania HTTP/odpowiedzi? –