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   public static Collection<String> lueTiedosto(String nimi, Collection<String> rivit) {
242       BufferedReader f = avaa_lukemista_varten(nimi);
243       return lueTiedosto(f, rivit);
244   }
245   
246   
247   /**
248    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonolistana
249    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
250    * @param nimi luettavan tiedoston nimi
251    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
252    */
253   public static List<String> lueTiedostoListaan(String nimi) {
254     ArrayList<String> rivit = new ArrayList<String>();
255     return (List<String>)lueTiedosto(nimi, rivit);
256   }
257   
258 
259   /**
260    * Funktiolla muutetaan tietorakenne merkkijonotaulukoksi
261    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
262    * @param rivit muutettava tietorakenne
263    * @return null jos rakenne on null, muuten rakenteen sisältö
264    */
265   public static String[] toArray(Collection<String> rivit) {
266       if ( rivit == null ) return null;
267       String [] tulosrivit = new String[rivit.size()];
268       int i=0;
269       for (String rivi:rivit) tulosrivit[i++] = rivi;
270       return tulosrivit;
271   }
272   
273   
274   /**
275    * Funktiolla luetaan tekstitiedosto ja palautetaan se merkkijonotaulukkona.
276    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
277    * @param nimi luettavan tiedoston nimi
278    * @return null jos tiedostoa ei saa luettua, muuten tiedoston sisältö
279    */
280   public static String[] lueTiedosto(String nimi) {
281       List<String> rivit = lueTiedostoListaan(nimi);
282       return toArray(rivit);
283   }
284   
285 
286   /**
287    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonolistana
288    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
289    * @param url luettavan tiedoston nimi
290    * @param rivit lista johon sivun rivit lisätään. 
291    * @return null jos sivua ei saa luettua, muuten sivun sisältö
292    */
293   public static Collection<String> lueNetista(String url, Collection<String> rivit) {
294       try {
295         URL sivu = new URL(url);
296           InputStream in = sivu.openStream();
297           Reader reader = new InputStreamReader(in);
298           BufferedReader f = new BufferedReader(reader);
299           return lueTiedosto(f,rivit);
300     } catch (MalformedURLException e) {
301         return null;
302     } catch (IOException e) {
303         // TODO Auto-generated catch block
304         return null;
305     }
306   }
307   
308   
309   /**
310    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonolistana
311    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
312    * @param url luettavan tiedoston nimi
313    * @return null jos sivua ei saa luettua, muuten sivun sisältö
314    */
315   public static List<String> lueNetistaListaan(String url) {
316       List<String> rivit = new ArrayList<String>();
317       return (List<String>)lueNetista(url, rivit);
318   }
319   
320   
321   /**
322    * Funktiolla luetaan nettisivun sisältö ja palautetaan se merkkijonotaulukkona
323    * Ei saa käyttää isojen tiedostojen käsittelyyn! 
324    * @param url luettavan tiedoston nimi
325    * @return null jos sivua ei saa luettua, muuten sivun sisältö
326    */
327   public static String[] lueNetista(String url) {
328       List<String> rivit = lueNetistaListaan(url);
329       return toArray(rivit);
330   }
331 
332   
333   /**
334    * Palauttaa onko nimi URL vai tavallinen tiedoston nimi
335    * @param nimi tutkittava nimi
336    * @return true jos URL, muuten false
337    * @example
338    * <pre name="test">
339    *   onkoURL("kissa.txt") === false;
340    *   onkoURL("http://i.jyu.fi") === true;
341    *   onkoURL("https://i.jyu.fi") === true;
342    *   onkoURL("httpko.txt") === false;
343    * </pre>
344    */
345   public static boolean onkoURL(String nimi) {
346       if ( nimi.startsWith("http:") ) return true;
347       if ( nimi.startsWith("https:") ) return true;
348       return false;
349   }
350   
351   
352   /**
353    * Lukee tiedosta tai netistä jos nimi alkaa http
354    * @param nimi tiedoston nimi tai URL
355    * @return taulukko luetuista merkkijonoista
356    */
357   public static String[] lue(String nimi) {
358      if ( onkoURL(nimi) )  return lueNetista(nimi);
359      return lueTiedosto(nimi);
360   }
361   
362   
363   /**
364    * Lukee tiedosta tai netistä jos nimi alkaa http
365    * @param nimi tiedoston nimi tai URL
366    * @return lista luetuista merkkijonoista
367    */
368   public static List<String> lueListaan(String nimi) {
369      if ( onkoURL(nimi) )  return lueNetistaListaan(nimi);
370      return lueTiedostoListaan(nimi);
371   }
372   
373   
374   /**
375    * Kirjoitetaan merkkijonotaulukko tiedostoon.
376    * @param nimi tiedoston nimi
377    * @param rivit kirjoitettavat rivit
378    * @param jatka jatketaanko vanhan tiedoston perään (true) vai ei (false) 
379    * @return false jos ei onnistu ja true jos onnistuu
380    */
381   public static boolean kirjoitaTiedosto(String nimi, String rivit[], boolean jatka) {
382       PrintWriter f = avaa_kirjoittamista_varten(nimi, jatka);
383       if ( f == null ) return false;
384       try {
385           for (String rivi : rivit)
386               f.println(rivi);
387       } finally {  
388           f.close();
389       }  
390       return true;   
391   }
392   
393   
394   /**
395    * Kirjoitetaan merkkijonotaulukko tiedostoon.
396    * @param nimi tiedoston nimi
397    * @param rivit kirjoitettavat rivit
398    * @return false jos ei onnistu ja true jos onnistuu
399    */
400   public static boolean kirjoitaTiedosto(String nimi, String rivit[]) {
401       return kirjoitaTiedosto(nimi, rivit, false);
402   }
403   
404   
405   /**
406    * Kirjoitetaan merkkijonolista tiedostoon.
407    * @param nimi tiedoston nimi
408    * @param rivit kirjoitettavat rivit
409    * @param jatka jatketaanko vanhan tiedoston perään (true) vai ei (false) 
410    * @return false jos ei onnistu ja true jos onnistuu
411    */
412   public static boolean kirjoitaTiedosto(String nimi, Iterable<String> rivit, boolean jatka) {
413       PrintWriter f = avaa_kirjoittamista_varten(nimi, jatka);
414       if ( f == null ) return false;
415       try {
416           for (String rivi : rivit)
417               f.println(rivi);
418       } finally {  
419           f.close();
420       }  
421       return true;   
422   }
423   
424   
425   /**
426    * Kirjoitetaan merkkijonolista tiedostoon.
427    * @param nimi tiedoston nimi
428    * @param rivit kirjoitettavat rivit
429    * @return false jos ei onnistu ja true jos onnistuu
430    */
431   public static boolean kirjoitaTiedosto(String nimi, Iterable<String> rivit) {
432       return kirjoitaTiedosto(nimi, rivit, false);
433   }
434   
435 }
436