NetBeansilla harjoitusmielessä teen pienimuotoista hallittua downloader-applicationia, mutta ongelma on nyt että en saa lukua toimimaan fiksusti; kirjoitettu tiedosto eroaa alkuperäisestä mikä luonnollisesti ei ole hyvä juttu.
Tässä luokka jolla hoidan luvun ja kirjoituksen:
package helloworld; import java.io.*; import java.net.URL; public class Downloader { String outputDirectory, URL; public Downloader(String outDir) { this.outputDirectory = outDir; } public void download(String URL, String filename) { try { System.out.println("Downloading: " + URL); URL dlURL = new URL(URL); DataOutputStream out = new DataOutputStream(new FileOutputStream(outputDirectory + filename)); BufferedReader in = new BufferedReader( new InputStreamReader( dlURL.openStream())); int i; while ((i = in.read()) != -1) { out.write(i); } in.close(); out.close(); } catch(Exception e) { System.out.println("Downloading failed"); } } }
Ja tässä esimerkki latauksesta:
Downloader dl = new Downloader("C:/temp/"); dl.download("https://www.ohjelmointiputka.net/img/palkki2.jpg", "testi.jpg");
Ja kuva on korruptoitunut... Syystä mitä en itse tiedä. ImageIO:lla nähtävästi onnistuisi kuvan lataaminen kyllä, mutta haluamani todellinen latauksen kohde ei ole kuva, vaan ihan muuta satunnaista binäärimössöä.
En tiedä miksi tuo lataus ei toimi oikein, mikäli sen hoitaa InputStreamReaderin kautta, mutta veikkaisin syynä olevan ongelmat merkistö(je)n kanssa. InputStream.read() lukee varmasti vain yhden tavun (arvo 0-255) ja OutputStream.write(int) kirjoittaa varmuudella tasan yhden tavun. Kun taas InputStreamReader.read() lukee ja OutputStreamWriter.write(int) kirjoittaa yhden merkin, jonka arvoalue voi käytetystä merkistöstä riippuen vaihdella. Siltikin tosin hieman kummastuttaa miksi se lukee palvelimelta/tiedostosta eri arvon kuin mitä siellä alunperin oli.
Seuraavalla tavalla muutetun koodin pitäisi toimia halutulla tavalla:
public void download(String URL, String filename) { try { System.out.println("Downloading: " + URL); URL dlURL = new URL(URL); OutputStream out = new FileOutputStream(new File(outputDirectory + filename)); InputStream in = dlURL.openStream(); int i; while ((i = in.read()) != -1) { out.write(i); } in.close(); out.close(); } catch(Exception e) { System.out.println("Downloading failed"); e.printStackTrace(); } }
Ja sillähän se toimiikin kyllä, kiitokset kovasti. Vähän oudolta vielä vaikuttaa vielä nämä erilaiset streamit, mutta ainakin saan nyt projektia etiäpäin (ja voin taas törmäillä uusiin ongelmiin) :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.