1   package fi.jyu.mit.ohj2;
2   import java.io.*;
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.List;
6   import java.net.MalformedURLException;
7   import java.net.URL;
8   
9   /**
10   * <p>Title: Tiedosto</p>
11   * <p>Description: Aliohjelmia tiedostojen käsittelyyn</p>
12   * <p>Copyright: Copyright (c) 2003</p>
13   * <p>Company: jyu </p>
14   * @author Vesa Lappalainen
15   * @version 1.0, 25.02.2003
16   * @version 1.1, 09.03.2002
17   * @version 1.2  12.08.2009 - netistä luku
18   * @version 1.3  06.11.2010 - lue, joka lukee netista tai tiedostosta
19   */
20  
21  public class Tiedosto {
22  
23  
24    /**
25     * Avaa tiedoston lukemista varten
26     * @param nimi avattavan tiedoston nimi
27     * @return avattu puskuroitu tiedostolukija tai null jos ei aukea
28     */
29    public static BufferedReader avaa_lukemista_varten(String nimi) { // NOPMD alleviiva ok hist. syistä
30      try {
31        return new BufferedReader(new FileReader(nimi));
32      } catch (FileNotFoundException ex) {
33        return null;
34      }
35    }
36  
37  
38    /**
39     * Avaa tiedoston kirjoittamista varten.
40     * @param nimi   avattavan tiedoston nimi
41     * @param jatka  jatketaanko edellisen tiedoston perään (true) vai ei (false)
42     * @return       avattu PrintWriter-olio tai null jos ei aukea
43     */
44    public static PrintWriter avaa_kirjoittamista_varten(String nimi,boolean jatka) {  // NOPMD alleviiva ok hist. syistä
45      PrintWriter f = null;
46        try {
47          f = new PrintWriter(new FileWriter(nimi,jatka));
48        } catch (IOException ex) {
49          return null;
50        }
51      return f;
52    }
53  
54    /**
55     * Avaa tiedoston kirjoittamista varten.
56     * @param nimi   avattavan tiedoston nimi
57     * @return       avattu PrintWriter-olio tai null jos ei aukea
58     */
59    public static PrintWriter avaa_kirjoittamista_varten(String nimi) {  // NOPMD alleviiva ok hist. syistä
60      return avaa_kirjoittamista_varten(nimi,false);
61    }
62  
63  
64    /**
65     * Avaa tiedoston kirjoittamista varten.
66     * @param nimi   avattavan tiedoston nimi
67     * @param jatka  jatketaanko edellisen tiedoston perään (true) vai ei (false)
68     * @return       avattu PrintStream-olio tai null jos ei aukea
69     */
70    public static PrintStream avaa_kirjoittamista_varten_stream(String nimi,boolean jatka) {  // NOPMD alleviiva ok hist. syistä
71      PrintStream f = null;
72      try {
73        f = new PrintStream(new FileOutputStream(nimi,jatka));
74      }  catch (FileNotFoundException ex) {
75        return null;
76      }
77      return f;
78    }
79  
80    /**
81     * Avaa tiedoston kirjoittamista varten.
82     * @param nimi   avattavan tiedoston nimi
83     * @return       avattu PrintStream-olio tai null jos ei aukea
84     */
85    public static PrintStream avaa_kirjoittamista_varten_stream(String nimi) {  // NOPMD alleviiva ok hist. syistä
86      return avaa_kirjoittamista_varten_stream(nimi,false);
87    }
88  
89  
90    /**
91     * Luo tarvittaessa uuden PrintStream-virran OutputStream virrasta.
92     * Jos os on valmiiksi PrintStream, niin tehdään vain tyypinmuunnos
93     * @param os virta josta luodaan PrintStream virta
94     * @return os muutettuna PrintStrean-virraksi
95     */
96    public static PrintStream getPrintStream(OutputStream os) {  // NOPMD alleviiva ok hist. syistä
97      return (os instanceof PrintStream)?(PrintStream)os : new PrintStream(os) ;
98    }
99  
100 
101   /**
102    * Tulostetaan tietovirtaan rivinvaihdolla erotettuna kaikki listan rivit
103    * @param out tietovirta johon tulostetaan
104    * @param rivit tulostettavat rivit
105    */
106   public static void println(PrintStream out, List<String> rivit) {
107       for (String s : rivit)
108           out.println(s);
109   }
110   
111   
112   /**
113    * Tulostetaan tietovirtaan rivinvaihdolla erotettuna kaikki taulukon rivit
114    * @param out tietovirta johon tulostetaan
115    * @param rivit tulostettavat rivit
116    */
117   public static void println(PrintStream out, String[] rivit) {
118       for (String s : rivit)
119           out.println(s);
120   }
121   
122   
123   /**
124    * Tulostetaan tietovirtaan erottimella erotettuna kaikki listan rivit
125    * @param out tietovirta johon tulostetaan
126    * @param rivit tulostettavat rivit
127    * @param erotin jolla rivit erotetaan
128    */
129   public static void print(PrintStream out, List<String> rivit, String erotin) {
130       String vali = "";
131       for (String s : rivit) {
132           out.println(vali+s);
133           vali = erotin;
134       }    
135   }
136   
137   
138   /**
139    * Tulostetaan tietovirtaan erottimella erotettuna kaikki taulukon rivit
140    * @param out tietovirta johon tulostetaan
141    * @param rivit tulostettavat rivit
142    * @param erotin jolla rivit erotetaan
143    */
144   public static void print(PrintWriter out, String[] rivit, String erotin) {
145       String vali = "";
146       for (String s : rivit) {
147           out.println(vali+s);
148           vali = erotin;
149       }    
150   }
151   
152   
153   /**
154    * Tulostetaan tietovirtaan rivinvaihdolla erotettuna kaikki listan rivit
155    * @param out tietovirta johon tulostetaan
156    * @param rivit tulostettavat rivit
157    */
158   public static void println(PrintWriter out, List<String> rivit) {
159       for (String s : rivit)
160           out.println(s);
161   }
162   
163   
164   /**
165    * Tulostetaan tietovirtaan rivinvaihdolla erotettuna kaikki taulukon rivit
166    * @param out tietovirta johon tulostetaan
167    * @param rivit tulostettavat rivit
168    */
169   public static void println(PrintWriter out, String[] rivit) {
170       for (String s : rivit)
171           out.println(s);
172   }
173   
174   
175   /**
176    * Tulostetaan tietovirtaan erottimella erotettuna kaikki listan rivit
177    * @param out tietovirta johon tulostetaan
178    * @param rivit tulostettavat rivit
179    * @param erotin jolla rivit erotetaan
180    */
181   public static void print(PrintWriter out, List<String> rivit, String erotin) {
182       String vali = "";
183       for (String s : rivit) {
184           out.println(vali+s);
185           vali = erotin;
186       }    
187   }
188   
189   
190   /**
191    * Tulostetaan tietovirtaan erottimella erotettuna kaikki taulukon rivit
192    * @param out tietovirta johon tulostetaan
193    * @param rivit tulostettavat rivit
194    * @param erotin jolla rivit erotetaan
195    */
196   public static void print(PrintStream out, String[] rivit, String erotin) {
197       String vali = "";
198       for (String s : rivit) {
199           out.println(vali+s);
200           vali = erotin;
201       }    
202   }
203   
204   
205   /**
206    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonolistana
207    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
208    * @param f avattu luettava tietovirta
209    * @param rivit lista johon tiedoston rivit lisätään. 
210    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
211    */
212   public static Collection<String> lueTiedosto(BufferedReader f, Collection<String> rivit) {
213     if ( f == null ) return null;
214     
215     String rivi;
216     
217     try {
218         while ( ( rivi = f.readLine() ) != null ) {
219             rivit.add(rivi);            
220         }
221     } catch (IOException e) {
222         return null;
223     } finally {
224         try {
225             f.close();
226         } catch (IOException e) {
227             return null;  // NOPMD
228         }        
229     }
230     return rivit;
231   }
232   
233   
234   /**
235    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonolistana
236    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
237    * @param nimi luettavan tiedoston nimi
238    * @param rivit lista johon tiedoston rivit lisätään. 
239    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
240    */
241   @SuppressWarnings("resource") // lueTiedosto sulkee
242   public static Collection<String> lueTiedosto(String nimi, Collection<String> rivit) {
243       BufferedReader f = avaa_lukemista_varten(nimi);
244       return lueTiedosto(f, rivit);
245   }
246   
247   
248   /**
249    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonolistana
250    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
251    * @param nimi luettavan tiedoston nimi
252    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
253    */
254   public static List<String> lueTiedostoListaan(String nimi) {
255     ArrayList<String> rivit = new ArrayList<String>();
256     return (List<String>)lueTiedosto(nimi, rivit);
257   }
258   
259 
260   /**
261    * Funktiolla muutetaan tietorakenne merkkijonotaulukoksi
262    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
263    * @param rivit muutettava tietorakenne
264    * @return null jos rakenne on null, muuten rakenteen sisältö
265    */
266   public static String[] toArray(Collection<String> rivit) {
267       if ( rivit == null ) return null;
268       String [] tulosrivit = new String[rivit.size()];
269       int i=0;
270       for (String rivi:rivit) tulosrivit[i++] = rivi;
271       return tulosrivit;
272   }
273   
274   
275   /**
276    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonotaulukkona.
277    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
278    * @param nimi luettavan tiedoston nimi
279    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
280    */
281   public static String[] lueTiedosto(String nimi) {
282       List<String> rivit = lueTiedostoListaan(nimi);
283       return toArray(rivit);
284   }
285   
286 
287   /**
288    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonolistana
289    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
290    * @param url luettavan tiedoston nimi
291    * @param rivit lista johon sivun rivit lisätään. 
292    * @return null jos sivua ei saa luettua, muuten sivun sisältö
293    */
294   @SuppressWarnings("resource") // lueTiedosto sulkee
295   public static Collection<String> lueNetista(String url, Collection<String> rivit) {
296       try {
297         URL sivu = new URL(url);
298           InputStream in = sivu.openStream();
299           Reader reader = new InputStreamReader(in);
300           BufferedReader f = new BufferedReader(reader);
301           return lueTiedosto(f,rivit);
302     } catch (MalformedURLException e) {
303         return null;
304     } catch (IOException e) {
305         // TODO Auto-generated catch block
306         return null;
307     }
308   }
309   
310   
311   /**
312    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonolistana
313    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
314    * @param url luettavan tiedoston nimi
315    * @return null jos sivua ei saa luettua, muuten sivun sisältö
316    */
317   public static List<String> lueNetistaListaan(String url) {
318       List<String> rivit = new ArrayList<String>();
319       return (List<String>)lueNetista(url, rivit);
320   }
321   
322   
323   /**
324    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonotaulukkona
325    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
326    * @param url luettavan tiedoston nimi
327    * @return null jos sivua ei saa luettua, muuten sivun sisältö
328    */
329   public static String[] lueNetista(String url) {
330       List<String> rivit = lueNetistaListaan(url);
331       return toArray(rivit);
332   }
333 
334   
335   /**
336    * Palauttaa onko nimi URL vai tavallinen tiedoston nimi
337    * @param nimi tutkittava nimi
338    * @return true jos URL, muuten false
339    * @example
340    * <pre name="test">
341    *   onkoURL("kissa.txt") === false;
342    *   onkoURL("http://i.jyu.fi") === true;
343    *   onkoURL("https://i.jyu.fi") === true;
344    *   onkoURL("httpko.txt") === false;
345    * </pre>
346    */
347   public static boolean onkoURL(String nimi) {
348       if ( nimi.startsWith("http:") ) return true;
349       if ( nimi.startsWith("https:") ) return true;
350       return false;
351   }
352   
353   
354   /**
355    * Lukee tiedosta tai netistä jos nimi alkaa http
356    * @param nimi tiedoston nimi tai URL
357    * @return taulukko luetuista merkkijonoista
358    */
359   public static String[] lue(String nimi) {
360      if ( onkoURL(nimi) )  return lueNetista(nimi);
361      return lueTiedosto(nimi);
362   }
363   
364   
365   /**
366    * Lukee tiedosta tai netistä jos nimi alkaa http
367    * @param nimi tiedoston nimi tai URL
368    * @return lista luetuista merkkijonoista
369    */
370   public static List<String> lueListaan(String nimi) {
371      if ( onkoURL(nimi) )  return lueNetistaListaan(nimi);
372      return lueTiedostoListaan(nimi);
373   }
374   
375   
376   /**
377    * Kirjoitetaan merkkijonotaulukko tiedostoon.
378    * @param nimi tiedoston nimi
379    * @param rivit kirjoitettavat rivit
380    * @param jatka jatketaanko vanhan tiedoston perään (true) vai ei (false) 
381    * @return false jos ei onnistu ja true jos onnistuu
382    */
383   public static boolean kirjoitaTiedosto(String nimi, String rivit[], boolean jatka) {
384       @SuppressWarnings("resource") // suljetaan finalyssä
385       PrintWriter f = avaa_kirjoittamista_varten(nimi, jatka);
386       if ( f == null ) return false;
387       try {
388           for (String rivi : rivit)
389               f.println(rivi);
390       } finally {  
391           f.close();
392       }  
393       return true;   
394   }
395   
396   
397   /**
398    * Kirjoitetaan merkkijonotaulukko tiedostoon.
399    * @param nimi tiedoston nimi
400    * @param rivit kirjoitettavat rivit
401    * @return false jos ei onnistu ja true jos onnistuu
402    */
403   public static boolean kirjoitaTiedosto(String nimi, String rivit[]) {
404       return kirjoitaTiedosto(nimi, rivit, false);
405   }
406   
407   
408   /**
409    * Kirjoitetaan merkkijonolista tiedostoon.
410    * @param nimi tiedoston nimi
411    * @param rivit kirjoitettavat rivit
412    * @param jatka jatketaanko vanhan tiedoston perään (true) vai ei (false) 
413    * @return false jos ei onnistu ja true jos onnistuu
414    */
415   public static boolean kirjoitaTiedosto(String nimi, Iterable<String> rivit, boolean jatka) {
416       @SuppressWarnings("resource") // suljetaan finalyssä
417       PrintWriter f = avaa_kirjoittamista_varten(nimi, jatka);
418       if ( f == null ) return false;
419       try {
420           for (String rivi : rivit)
421               f.println(rivi);
422       } finally {  
423           f.close();
424       }  
425       return true;   
426   }
427   
428   
429   /**
430    * Kirjoitetaan merkkijonolista tiedostoon.
431    * @param nimi tiedoston nimi
432    * @param rivit kirjoitettavat rivit
433    * @return false jos ei onnistu ja true jos onnistuu
434    */
435   public static boolean kirjoitaTiedosto(String nimi, Iterable<String> rivit) {
436       return kirjoitaTiedosto(nimi, rivit, false);
437   }
438   
439 }
440