VertaaTiedosto.java |
1 package fi.jyu.mit.ohj2; 2 import java.io.*; 3 import java.util.Scanner; 4 5 /** 6 * Aliohjelma kahden tekstitiedoston vertaamiseksi. 7 * Käyttö lähinnä JUnit testeissä esim. seuraavasti: 8 * <pre> 9 * VertaaTiedosto.kirjoitaTiedosto("hiljaa.txt", 10 * "33 hiljaa 1 hiipii\n"+ 11 * "hyvä 33 tulee\n"+ 12 * "36 1 3 5 55\n"+ 13 * "nyt 33 riittää\n"); 14 * VertaaTiedosto.kirjoitaTiedosto("hiljaayli30.txt", 15 * "33 hiljaa 1 hiipii\n"+ 16 * "36 1 3 5 55\n"); 17 * VertaaTiedosto.tuhoaTiedosto("tulos.txt"); 18 * TulYli30.main(new String[]{"hiljaa.txt","tulos.txt"}); 19 * String virhe=VertaaTiedosto.vertaa("tulos.txt","hiljaayli30.txt"); 20 * if ( virhe != null ) fail(virhe); 21 * </pre> 22 * @author vesal 23 * @version 10.3.2007 24 */ 25 public class VertaaTiedosto { // NOPMD Cyclomatic 26 /** 27 * Verrataan kahta tekstitiedostoa ja heti kun tulee ensimmäin poikkeava 28 * rivi palautetaanvirhe. Lopussa olevat pelkkä yksi rivi ei tee eroa. 29 * @param nimi1 1. verrattavan tiedoston nimi 30 * @param nimi2 2. verrattavan tiedoston nimi 31 * @return ensimmäinen eroavaisuus joka löytyy. Null jos ei eroja. 32 * @throws IOException jos lukemisessa tapahtuu virhe. 33 * @example 34 * <pre name="test"> 35 * #THROWS IOException 36 * #import java.io.*; 37 * #STATICIMPORT 38 * kirjoitaTiedosto("hiljaa1.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); 39 * 40 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); 41 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === null; 42 * 43 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee"); 44 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === null; 45 * 46 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n\n\n"); 47 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === "Rivi 3: hiljaa1.txt loppui ensin, hiljaa2.txt on "; 48 * 49 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\nhyvä 34 tulee\n"); 50 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === "Ero riveissä 2: hyvä 33 tulee ja hyvä 34 tulee"; 51 * 52 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\n"); 53 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === "Rivi 2: hiljaa2.txt loppui ensin, hiljaa1.txt on hyvä 33 tulee"; 54 * 55 * kirjoitaTiedosto("hiljaa2.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\nja 34 tulee\n"); 56 * vertaaFileFile("hiljaa1.txt","hiljaa2.txt") === "Rivi 3: hiljaa1.txt loppui ensin, hiljaa2.txt on ja 34 tulee"; 57 * vertaaFileFile("hiljaa1.txt","hiljaa3.txt") === "Tiedosto ei aukea: hiljaa3.txt"; 58 * vertaaFileFile("hiljaa4.txt","hiljaa2.txt") === "Tiedosto ei aukea: hiljaa4.txt"; 59 * 60 * tuhoaTiedosto("hiljaa1.txt"); 61 * tuhoaTiedosto("hiljaa2.txt"); 62 * 63 * </pre> 64 */ 65 public static String vertaaFileFile(String nimi1, String nimi2) throws IOException { // NOPMD 66 BufferedReader f1 = null; 67 BufferedReader f2 = null; 68 try { 69 f1 = Tiedosto.avaa_lukemista_varten(nimi1); 70 f2 = Tiedosto.avaa_lukemista_varten(nimi2); 71 if ( f1 == null ) return "Tiedosto ei aukea: " + nimi1; 72 if ( f2 == null ) return "Tiedosto ei aukea: " + nimi2; 73 int n = 1; 74 75 while (true) { 76 String s1 = f1.readLine(); 77 String s2 = f2.readLine(); 78 if (s1 == null && s2 == null ) return null; 79 if (s1 != null && s2 == null ) return "Rivi "+ n + ": " + nimi2 + " loppui ensin, " + nimi1 + " on "+ s1; // NOPMD 80 if (s1 == null && s2 != null) return "Rivi "+ n + ": " + nimi1 + " loppui ensin, " + nimi2 + " on "+ s2; // NOPMD 81 if ( s1.compareTo(s2) != 0 ) return "Ero riveissä " + n + ": " + s1 + " ja " + s2; // NOPMD 82 n++; 83 } 84 } finally { 85 if (f1 != null) 86 f1.close(); 87 if (f2 != null) 88 f2.close(); 89 } 90 } 91 92 /** 93 * Verrataan tekstitiedostoa merkkijonoon ja heti kun tulee ensimmäinen poikkeava 94 * rivi palautetaan virhe. Lopussa olevat pelkkä yksi tyhkä rivi eo tee eroa. 95 * @param nimi1 1. verrattavan tiedoston nimi 96 * @param ss2 2. verrattava sisältö 97 * @return ensimmäinen eroavaisuus joka löytyy. Null jos ei eroja. 98 * @throws IOException jos lukemisessa tapahtuu virhe. 99 * <pre name="test"> 100 * #THROWS IOException 101 * #import java.io.*; 102 * #STATICIMPORT 103 * kirjoitaTiedosto("hiljaa1.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); 104 * 105 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 33 tulee\n") === null; 106 * 107 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 33 tulee") === null; 108 * 109 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 33 tulee\n\n") === "Rivi 3: hiljaa1.txt loppui ensin, jono on "; 110 * 111 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 33 tulee\n\n\n") === "Rivi 3: hiljaa1.txt loppui ensin, jono on "; 112 * 113 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 34 tulee\n") === "Ero riveissä 2: hyvä 33 tulee ja hyvä 34 tulee"; 114 * 115 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\n") === "Rivi 2: Jono loppui ensin, hiljaa1.txt on hyvä 33 tulee"; 116 * 117 * vertaaFileString("hiljaa1.txt","33 hiljaa 1 hiipii\nhyvä 33 tulee\nja 34 tulee\n") === "Rivi 3: hiljaa1.txt loppui ensin, jono on ja 34 tulee"; 118 * vertaaFileString("hiljaa1.txt",null) === "Jono on null"; 119 * vertaaFileString("hiljaa4.txt","hiljaa2.txt") === "Tiedosto ei aukea: hiljaa4.txt"; 120 * 121 * tuhoaTiedosto("hiljaa1.txt"); 122 * 123 * </pre> 124 */ 125 public static String vertaaFileString(String nimi1, String ss2) throws IOException { // NOPMD 126 if ( ss2 == null ) return "Jono on null"; 127 BufferedReader f1 = null; 128 Scanner f2 = new Scanner(ss2); 129 int n = 1; 130 try { 131 f1 = Tiedosto.avaa_lukemista_varten(nimi1); 132 if ( f1 == null ) return "Tiedosto ei aukea: " + nimi1; 133 134 while (true) { 135 String s1 = f1.readLine(); 136 boolean b2 = f2.hasNextLine(); 137 String s2 = null; 138 if ( b2 ) s2 = f2.nextLine(); 139 if (s1 == null && !b2) return null; 140 if (s1 != null && !b2 ) return "Rivi "+ n + ": " + "Jono loppui ensin, " + nimi1 + " on "+ s1; 141 if (s1 == null && b2) return "Rivi "+ n + ": " + nimi1 + " loppui ensin, " + "jono on "+ s2; 142 if ( s1.compareTo(s2) != 0 ) return "Ero riveissä " + n + ": " + s1 + " ja " + s2; 143 n++; 144 } 145 } finally { 146 if (f1 != null) 147 f1.close(); 148 } 149 } 150 151 /** 152 * Verrataan kahta tekstitiedoston kaltaista merkkijonoa ja heti kun tulee ensimmäinen poikkeava 153 * rivi palautetaan virhe. Lopussa oleva yksi tyhjä rivi ei tee eroa. 154 * @param ss1 1. verrattava sisältö 155 * @param ss2 2. verrattava sisältö 156 * @return ensimmäinen eroavaisuus joka löytyy. Null jos ei eroja. 157 * <pre name="test"> 158 * #THROWS IOException 159 * #import java.io.*; 160 * #STATICIMPORT 161 * vertaaString2("","\n") === "Rivi 1: 1. loppui ensin, 2. on "; 162 * vertaaString2("kissa\n","kissa") === null; 163 * vertaaString2("\n\n","\n") === "Rivi 2: 2. loppui ensin, 1. on "; 164 * vertaaString2("\r\n","\n") === null; 165 * vertaaString2("\r\n","\n\n") === "Rivi 2: 1. loppui ensin, 2. on "; 166 * vertaaString2("33 hiljaa 1 hiipii\r\nhyvä 33 tulee\r\n","33 hiljaa 1 hiipii\nhyvä 33 tulee\n") === null; 167 * vertaaString2("a b","a c") === "Ero riveissä 1: a b ja a c" 168 * vertaaString2(null,null) === null; 169 * vertaaString2(null," ") === "1. on null"; 170 * vertaaString2(" ",null) === "2. on null"; 171 * </pre> 172 */ 173 public static String vertaaString2(String ss1, String ss2) { // NOPMD 174 if ( ss1 == null & ss2 == null ) return null; 175 if ( ss1 == null ) return "1. on null"; 176 if ( ss2 == null ) return "2. on null"; 177 Scanner f1 = new Scanner(ss1); 178 Scanner f2 = new Scanner(ss2); 179 int n = 1; 180 while (true) { 181 String s1 = null; 182 String s2 = null; 183 boolean b1 = f1.hasNextLine(); 184 boolean b2 = f2.hasNextLine(); 185 if ( b1 ) s1 = f1.nextLine(); 186 if ( b2 ) s2 = f2.nextLine(); 187 if ( !b1 && !b2) return null; 188 if ( b1 && !b2 ) return "Rivi "+ n + ": " + "2. loppui ensin, 1. on "+ s1; 189 if ( !b1 && b2) return "Rivi "+ n + ": " + "1. loppui ensin, 2. on "+ s2; 190 if ( s1.compareTo(s2) != 0 ) return "Ero riveissä " + n + ": " + s1 + " ja " + s2; 191 n++; 192 } 193 } 194 195 /** 196 * Verrataan kahta tekstitiedoston kaltaista merkkijonoa ja heti kun tulee ensimmäinen poikkeava 197 * rivi palautetaan virhe. Lopussa olevat pelkät tyhjät rivit merkitsevät. 198 * @param ss1 1. verrattava sisältö 199 * @param ss2 2. verrattava sisältö 200 * @return ensimmäinen eroavaisuus joka löytyy. Null jos ei eroja. 201 * <pre name="test"> 202 * #THROWS IOException 203 * #import java.io.*; 204 * #STATICIMPORT 205 * vertaaString("kissa\n","kissa") === "Rivi 2: 2. loppui ensin, 1. on "; 206 * vertaaString("","\n") === "Rivi 1: 1. loppui ensin, 2. on "; 207 * vertaaString("\n\n","\n") === "Rivi 3: 2. loppui ensin, 1. on "; 208 * vertaaString("\r\n","\n") === null; 209 * vertaaString("\r","\n") === null; 210 * vertaaString("\r\n","\n\n") === "Rivi 3: 1. loppui ensin, 2. on "; 211 * vertaaString("33 hiljaa 1 hiipii\r\nhyvä 33 tulee\r\n","33 hiljaa 1 hiipii\nhyvä 33 tulee\n") === null; 212 * vertaaString("a b","a c") === "Ero riveissä 1: a b ja a c" 213 * vertaaString(null,null) === null; 214 * vertaaString(null," ") === "1. on null"; 215 * vertaaString(" ",null) === "2. on null"; 216 * </pre> 217 */ 218 public static String vertaaString(String ss1, String ss2) { // NOPMD 219 if ( ss1 == null & ss2 == null ) return null; 220 if ( ss1 == null ) return "1. on null"; 221 if ( ss2 == null ) return "2. on null"; 222 ss1 = ss1.replaceAll("\\r\\n", "\n"); 223 ss2 = ss2.replaceAll("\\r\\n", "\n"); 224 ss1 = ss1.replaceAll("\\r", "\n"); 225 ss2 = ss2.replaceAll("\\r", "\n"); // Toki nyt voitaisiin verrata pelkkiä jonoja sellaisenaan 226 Erottelija f1 = new Erottelija(ss1,"\n"); 227 Erottelija f2 = new Erottelija(ss2,"\n"); 228 int n = 1; 229 while (true) { 230 String s1 = null; 231 String s2 = null; 232 boolean b1 = f1.hasMoreTokens(); 233 boolean b2 = f2.hasMoreTokens(); 234 if ( b1 ) s1 = f1.nextToken(); 235 if ( b2 ) s2 = f2.nextToken(); 236 if ( !b1 && !b2) return null; 237 if ( b1 && !b2 ) return "Rivi "+ n + ": " + "2. loppui ensin, 1. on "+ s1; 238 if ( !b1 && b2) return "Rivi "+ n + ": " + "1. loppui ensin, 2. on "+ s2; 239 if ( s1.compareTo(s2) != 0 ) return "Ero riveissä " + n + ": " + s1 + " ja " + s2; 240 n++; 241 } 242 } 243 244 /** 245 * Kirjoitetaan tiedostoon sisältö 246 * @param nimi tiedoston nimi johon kirjoitetaan 247 * @param sisalto merkkijono joka kirjoitetaan tiedostoon 248 * @throws IOException jos tiedosto ei aukea. 249 * @example 250 * <pre name="test"> 251 * #THROWS IOException 252 * kirjoitaTiedosto("hiljaa1.txt", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); 253 * tuhoaTiedosto("hiljaa1.txt"); 254 * kirjoitaTiedosto("ö:\\ö.ö", "33 hiljaa 1 hiipii\nhyvä 33 tulee\n"); #THROWS IOException 255 * </pre> 256 */ 257 public static void kirjoitaTiedosto(String nimi, String sisalto) throws IOException { 258 PrintWriter out = null; 259 try { 260 out = new PrintWriter(new FileWriter(nimi)); 261 out.write(sisalto); 262 out.close(); 263 } finally { 264 if (out != null) 265 out.close(); 266 } 267 } 268 269 /** 270 * Tuhotaan tiedosto levyltä 271 * @param nimi tuhottavan tiedoston nimi 272 */ 273 public static void tuhoaTiedosto(String nimi) { 274 File f = new File(nimi); 275 f.delete(); 276 } 277 278 /** 279 * Testataan tiedostojen vertaamista 280 * @param args ei käytössä 281 * @throws IOException jos tulee virhe 282 */ 283 /* 284 public static void main(String[] args) throws IOException { 285 String koe = vertaaFileFile("fi/jyu/mit/ohj2/IO.java","fi/jyu/mit/ohj2/Syotto.java"); 286 System.out.println(koe); 287 } 288 */ 289 } 290