Suuntaaja.java |
1 package fi.jyu.mit.ohj2; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.io.OutputStream; 11 import java.io.PrintStream; 12 13 /** 14 * Luokka tietovirtojen uudelleen suuntaamiseksi 15 * @author vesal 16 * 17 */ 18 public class Suuntaaja { // NOPMD -luokkakirjasto 19 // #STATICIMPORT 20 // #import fi.jyu.mit.ohj2.*; 21 22 /** 23 * Rajapinta suuntajalle 24 * @author vesal 25 * 26 */ 27 public interface ISuuntaaja { 28 29 /** 30 * Palauttaa suuntauksen alkuperäiseen tilaan. 31 */ 32 void palauta(); 33 } 34 35 /** 36 * Käytössä olevan systeemin rivinvahdon merkkkijono 37 */ 38 private static String NL = getNL(); // NOPMD - tarkoituksella lyhyt nimi 39 40 41 /** 42 * Palauttaa systeemin käytössä olevan newline jonon 43 * @return rivinvaihdon merkkiyhdistelmä käytetyssä järjestelmässä 44 */ 45 public static String getNL() { 46 if ( NL != null ) return NL; 47 NL = ""; 48 StringOutput so = new StringOutput(); 49 System.out.println(); 50 NL = so.toString(); 51 so.palauta(); 52 return NL; 53 } 54 55 56 /** 57 * Suuntaa inputin uudelleen ja kertoo Syotto-luokalle 58 * @param is uusi tietovirta syötölle 59 * 60 */ 61 protected static void setIn(InputStream is) { 62 System.setIn(is); 63 Syotto.alusta(); 64 Readkey.init(); 65 } 66 67 /** 68 * Luokka jolla System.in otetaan tiedostosta 69 * @author vesal 70 * @version 11.3.2007 71 */ 72 public static class Input implements ISuuntaaja { 73 private static final InputStream origIn = System.in; // NOPMD - ei ole vakio 74 private InputStream stdin = null; 75 76 /** 77 * Asetetaan peruslukuvirta eri tiedostoon. 78 * Jos nimi on null, niin sitä virtaa ei suunnata uudelleen 79 * @param inNimi mistä tiedostosta System.in luetaan 80 * @throws FileNotFoundException jos tiedostoa ei saada käyttöön 81 * @example 82 * <pre name="test"> 83 * #THROWS IOException 84 * #import java.io.*; 85 * #import java.util.*; 86 * #import static fi.jyu.mit.ohj2.VertaaTiedosto.*; 87 * kirjoitaTiedosto("hiljaa1.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); 88 * Input in = new Input("hiljaa1.txt"); 89 * Scanner sc = new Scanner(System.in); 90 * sc.nextLine() === "33 hiljaa 1 hiipii"; 91 * sc.nextLine() === "hyvä 33 tulee"; 92 * sc.hasNextLine() === false; 93 * in.palauta(); 94 * tuhoaTiedosto("hiljaa1.txt"); 95 * in = new Input(null); 96 * in.palauta(); 97 * </pre> 98 */ 99 public Input(String inNimi) throws FileNotFoundException { 100 // getNL(); 101 if ( inNimi != null ) { 102 stdin = new FileInputStream(inNimi); 103 setIn(stdin); 104 } 105 } 106 107 /** 108 * Palautetaan tietovirta takaisin alkuperäiseen tilaan 109 */ 110 public void palauta() { 111 if ( stdin != null ) { 112 try { 113 stdin.close(); 114 } catch (IOException e) { // NOPMD 115 } 116 setIn(origIn); 117 } 118 } 119 120 } 121 122 /** 123 * Luokka jolla System.out suunnataan toiseen tiedostoon 124 * @author vesal 125 * @version 11.3.2007 126 */ 127 public static class Output implements ISuuntaaja { 128 private static final PrintStream origOut = System.out; // NOPMD - ei ole vakio 129 private PrintStream stdout = null; 130 131 /** 132 * Asetetaan perustulostusvirta eri tiedostoon. 133 * Jos nimi on null, niin sitä virtaa ei suunnata uudelleen 134 * @param outNimi mihin System.out kirjoitetaan 135 * @throws FileNotFoundException jos tiedostoa ei saada käyttöön 136 * @example 137 * <pre name="test"> 138 * #THROWS IOException 139 * #import java.io.*; 140 * #import java.util.*; 141 * #import static fi.jyu.mit.ohj2.VertaaTiedosto.*; 142 * Output out = new Output("hiljaa1.txt"); 143 * System.out.println("eka"); 144 * System.out.println("toka"); 145 * out.palauta(); 146 * vertaaFileString("hiljaa1.txt","eka\ntoka\n") === null; 147 * tuhoaTiedosto("hiljaa1.txt"); 148 * 149 * out = new Output(null); 150 * out.palauta(); 151 * </pre> 152 */ 153 public Output(String outNimi) throws FileNotFoundException { 154 // getNL(); 155 if ( outNimi != null ) { 156 stdout = new PrintStream(new FileOutputStream(outNimi)); 157 System.setOut(stdout); 158 } 159 } 160 161 /** 162 * Palautetaan tietovirta takaisin alkuperäiseen tilaan 163 */ 164 public void palauta() { 165 if (stdout != null ) { 166 stdout.close(); 167 System.setOut(origOut); 168 } 169 } 170 171 } 172 173 /** 174 * Luokka syötön lukemiseksi merkkijonosta 175 * @author vesal 176 * @version 2.2.2008 177 * @example 178 * <pre name="test"> 179 * StringInput si = new StringInput("kissa\nkoira"); 180 * StringOutput so = new StringOutput(); 181 * Syotto.kysy("Mikä") === "kissa"; 182 * Syotto.kysy("Mikä") === "koira"; 183 * Syotto.kysy("Mikä") === ""; 184 * si = new StringInput("12\n13"); 185 * Syotto.kysy("Luku",0) === 12; 186 * Syotto.kysy("Luku",0) === 13; 187 * Syotto.kysy("Luku",0) === 0; 188 * si.palauta(); 189 * so.palauta(); 190 * </pre> 191 * 192 */ 193 public static class StringInput implements ISuuntaaja { 194 private static final InputStream origIn = System.in; // NOPMD ei ole vakio 195 private ByteArrayInputStream byteinput; 196 197 198 /** 199 * Alustetataan lukutietovirta 200 * @param inputString merkkijonojosta input otetaan 201 */ 202 public StringInput(String inputString) { 203 byteinput = new ByteArrayInputStream(inputString.getBytes()); 204 setIn(byteinput); 205 } 206 207 /** 208 * Palautetaan tietovirta takaisin alkuperäiseen tilaan 209 */ 210 public void palauta() { 211 setIn(origIn); 212 } 213 214 /** 215 * Laitetaan syöttöön uusi merkkijono jota luetaan- 216 * @param inputString merkkijonojosta input otetaan 217 * @example 218 * <pre name="test"> 219 * StringInput si = new StringInput("kissa\nkoira"); 220 * StringOutput so = new StringOutput(); 221 * Syotto.kysy("Mikä") === "kissa"; 222 * Syotto.kysy("Mikä") === "koira"; 223 * Syotto.kysy("Mikä") === ""; 224 * si.input("12\n13"); 225 * Syotto.kysy("Luku",0) === 12; 226 * Syotto.kysy("Luku",0) === 13; 227 * Syotto.kysy("Luku",0) === 0; 228 * si.palauta(); 229 * so.palauta(); 230 * </pre> 231 */ 232 public void input(String inputString) { 233 byteinput = new ByteArrayInputStream(inputString.getBytes()); 234 setIn(byteinput); 235 } 236 } 237 238 239 /** 240 * Luokka tulostuksen siirtämiseksi merkkijonoon 241 * @author vesal 242 * @version 2.2.2008 243 * 244 */ 245 public static class StringOutput implements ISuuntaaja { 246 private static final PrintStream origOut = System.out; // NOPMD - ei ole vakio 247 private final ByteArrayOutputStream byteoutput; 248 249 /** 250 * Alutetataan kirjoitustietovirta 251 */ 252 public StringOutput() { 253 // if ( NL != null ) getNL(); 254 byteoutput = new ByteArrayOutputStream(); 255 PrintStream ps = new PrintStream(byteoutput); 256 System.setOut(ps); 257 } 258 259 /** 260 * Palautetaan tietovirta takaisin alkuperäiseen tilaan 261 */ 262 public void palauta() { 263 System.setOut(origOut); 264 } 265 266 /** 267 * Palautetaan toistaiseksi tulostettu tieto merkkijonona 268 * @return tulostettu tieto 269 * @example 270 * <pre name="test"> 271 * String NL = getNL(); 272 * StringOutput so = new StringOutput(); 273 * System.out.println("eka"); 274 * System.out.println("toka"); 275 * so.toString() === "eka"+NL+"toka"+NL; 276 * System.out.println("kolmas"); 277 * so.toStringReset() === "eka"+NL+"toka"+NL+"kolmas"+NL; 278 * so.toString() === ""; 279 * System.out.println("neljäs"); 280 * so.toStringReset() === "neljäs"+NL; 281 * System.out.print("viides\nkuudes"); 282 * so.toStringReset() === "viides\nkuudes"; 283 * System.out.printf("viides%nkuudes"); 284 * so.toStringReset() === "viides"+NL+"kuudes"; 285 * so.palauta(); 286 * </pre> 287 */ 288 @Override 289 public String toString() { 290 return byteoutput.toString(); 291 } 292 293 /** 294 * Palautetaan toistaiseksi tulostettu tieto merkkijonona 295 * ja tyhjennetään tietovirta 296 * @return tulostettu tieto 297 */ 298 public String toStringReset() { 299 String result = byteoutput.toString(); 300 reset(); 301 return result; 302 } 303 304 /** 305 * Tyhjentää toistaiseksi tulostetun osan 306 */ 307 public void reset() { 308 byteoutput.reset(); 309 } 310 311 /** 312 * Kirjoittaa sisällön tietovirtaan 313 * @param out virta johon kirjoitetaan 314 * @throws IOException jos joku menee pieleen 315 * @example 316 * <pre name="test"> 317 * #THROWS IOException 318 * PrintStream fs = Tiedosto.avaa_kirjoittamista_varten_stream("hiljaa1.txt"); 319 * StringOutput so = new StringOutput(); 320 * System.out.println("eka"); 321 * System.out.println("toka"); 322 * so.writeTo(fs); 323 * fs.close(); 324 * so.palauta(); 325 * vertaaFileString("hiljaa1.txt","eka\ntoka\n") === null; 326 * tuhoaTiedosto("hiljaa1.txt"); 327 * </pre> 328 */ 329 public void writeTo(OutputStream out) throws IOException { 330 byteoutput.writeTo(out); 331 } 332 333 /** 334 * Palauttaa alkuperäisen tietovirran 335 * @return alkuperäinen tietovirta 336 */ 337 public PrintStream getOrigOut() { 338 return origOut; 339 } 340 341 /** 342 * Vertaa tuloksen sisältöä jonoon ja palauttaa eron 343 * tai null jos samat. Tyhjentää tulosteen. 344 * @param verrattava jono johon output-jonon sisältöä verrataan 345 * @return null jos samat, muuten 1. ero 346 * @example 347 * <pre name="test"> 348 * StringOutput so = new StringOutput(); 349 * System.out.println("eka"); 350 * System.out.println("toka"); 351 * so.ero("eka\ntoka\n") === null; 352 * System.out.println("kolmas"); 353 * so.ero("eka\ntoka\nkolmas\n") === "Ero riveissä 1: kolmas ja eka"; 354 * so.toString() === ""; 355 * System.out.println("neljäs"); 356 * so.ero("neljäs\n") === null; 357 * System.out.print("viides\nkuudes"); 358 * so.ero("viides\nkuudes") === null; 359 * System.out.printf("viides%nkuudes"); 360 * so.ero("viides\nkuudes") === null; 361 * so.palauta(); 362 * so.getOrigOut() == System.out === true; 363 * </pre> 364 */ 365 public String ero(String verrattava) { 366 return VertaaTiedosto.vertaaString(toStringReset(), verrattava); 367 } 368 369 } 370 371 372 373 /** 374 * Luokka jolla System.in ja System.out suunnataan toiseen tiedostoon 375 * @author vesal 376 * @version 11.3.2007 377 */ 378 public static class InOut implements ISuuntaaja { 379 private final Input in; 380 private final Output out; 381 382 /** 383 * Asetetaan perusluku- ja tulostusvirta eri tiedostoon. 384 * Jos jompikumpi nimi on null, niin sitä virtaa ei suunnata uudelleen 385 * @param inNimi mistä tiedostosta System.in luetaan 386 * @param outNimi mihin System.out kirjoitetaan 387 * @throws FileNotFoundException jos tiedostoa ei saada käyttöön 388 * @example 389 * <pre name="test"> 390 * #THROWS IOException 391 * kirjoitaTiedosto("hiljaa1.txt", "eka\ntoka\n"); 392 * InOut io = new InOut("hiljaa1.txt","hiljaa2.txt"); 393 * Syotto.kysy("1.") === "eka"; 394 * Syotto.kysy("2.") === "toka"; 395 * Syotto.kysy("3.") === ""; 396 * io.palauta(); 397 * tuhoaTiedosto("hiljaa1.txt"); 398 * vertaaFileString("hiljaa2.txt","1. >2. >3. >") === null; 399 * tuhoaTiedosto("hiljaa2.txt"); 400 * </pre> 401 */ 402 public InOut(String inNimi, String outNimi) throws FileNotFoundException { 403 in = new Input(inNimi); 404 out = new Output(outNimi); 405 } 406 407 /** 408 * Palautetaan tietovirrat takaisin alkuperäiseen tilaan 409 */ 410 public void palauta() { 411 in.palauta(); 412 out.palauta(); 413 } 414 415 } 416 417 /** 418 * Testataan suuntaamista 419 * @param args ei käytössä 420 */ 421 /* 422 public static void main(String[] args) { 423 StringInput si = new StringInput("kissa\nkoira\nkana"); 424 StringOutput so = new StringOutput(); 425 String s1 = Syotto.kysy("Mikä"); 426 String so1 = so.toString(); 427 so.getOrigOut().println("so1=" + so1); 428 si = new StringInput("12\n13\n15\n16\n17"); 429 String s2 = Syotto.kysy("Kuka"); 430 //si.palauta(); 431 String s3 = Syotto.kysy("Mikä"); 432 so.reset(); 433 so.getOrigOut().println(s1 + "|" + s2 + "|" + s3); 434 String s4 = Syotto.kysy("Kuis"); 435 System.out.println(s4); 436 si = new StringInput("12\n13\n15\n16\n17"); 437 Scanner sc = new Scanner(System.in); 438 String s5 = sc.nextLine(); 439 String s6 = Syotto.kysy("No"); 440 si.palauta(); 441 String so2 = so.toString(); 442 so.palauta(); 443 System.out.println(so1 + "|" + so2 + "|" + s5 + "|" + s6); 444 } 445 */ 446 } 447