2009-09-25 12 views
7

Mam oprogramowanie, które pozwala pisać dodatki w plikach javascript (.js), które pozwalają na korzystanie z funkcji Java (nie wiem, czy to jest typowe, nigdy nie widziałem wywołanie java w pliku javascript wcześniej)Napisz pobrany plik binarny na dysk w Javie

Potrzebuję pobrać plik binarny z serwera WWW i zapisać go na dysku twardym. Próbowałem następujący kod:

baseencoder = new org.apache.commons.codec.binary.Base64(); 
url = new java.net.URL("https://server/file.tgz"); 

urlConnect = url.openConnection(); 
urlConnect.setDoInput(true); 
urlConnect.setDoOutput(true); 
urlConnect.setRequestProperty("authorization","Basic "+ java.lang.String(baseencoder.encodeBase64(java.lang.String(username + ":" + password).getBytes()))); 
urlConnect.setRequestProperty("content-type","application/x-www-form-urlencoded"); 

is = new java.io.DataInputStream(urlConnect.getInputStream()); 
fstream = new FileWriter("C:\\tmp\\test.tgz"); 
out = new BufferedWriter(fstream); 
while((data = is.read()) != -1){ 
    out.write(data); 
} 

out.close(); 
is.close(); 

Wynikowy plik nie jest już prawidłowym archiwum gzip. Przepraszam, jeśli popełniłem wielki błąd, ale nie jestem programistą i nie znam zbyt wiele Java.

Odpowiedz

33

Nie używaj FileWriter - próbujesz przekonwertować dane na tekst.

Po prostu użyj FileOutputStream.

byte[] buffer = new byte[8 * 1024]; 

InputStream input = urlConnect.getInputStream(); 
try { 
    OutputStream output = new FileOutputStream(filename); 
    try { 
    int bytesRead; 
    while ((bytesRead = input.read(buffer)) != -1) { 
     output.write(buffer, 0, bytesRead); 
    } 
    } finally { 
    output.close(); 
    } 
} finally { 
    input.close(); 
} 
+1

Należy również użyć poprawnego warunku testu w pętli while: while ((data = ** jest **. Read())! = Null) {...}. –

+0

Dzięki za pomocą pliku FileOutputStream działa (nadal używam tylko prostego read(), ponieważ wydaje się, że nie można używać bufora bajtowego w javascript, ponieważ nie jest to obiekt. – radius

2

DataInputStream jest przeznaczona do czytania prymitywów Java, a nie dla danych generycznych.

Jest również zbędny, ponieważ urlConnect.getInputStream(); już zwraca obiekt InputStream, a wszystkie metody InputStream obsługują funkcję read().

is = urlConnect.getInputStream(); 

P.S. Zakłada to, że is i są tą samą zmienną. W przeciwnym razie czytasz niewłaściwy strumień w pętli.

+0

bis był literówka, poprawiłem go, dziękuję – radius

+0

Nice Informacja! Ciekawe, że pomimo tego, co sugeruje nazwa, DataInputStream nie jest dla ogólnych danych ..! – Gewure

9

Wiem, że to pytanie jest już odpowiedź, ale prostszym sposobem jest użycie IOUtils.copy() metodę Apache Commons IO, który może w pełni skopiować InputStream do OutputStream.

0

Po prostu przeczytaj o LimitInputStream brzmi jak robi dokładnie to, co robisz, buforowanie strumienia wejściowego dla większej efektywności.