001package bradleyross.library.helpers; 002import java.net.URL; 003import java.net.URLConnection; 004import java.io.File; 005import java.io.FileReader; 006import java.io.OutputStream; 007import java.io.InputStream; 008import java.io.FileInputStream; 009import java.io.IOException; 010import java.io.FileNotFoundException; 011import java.util.Map; 012import java.util.List; 013import java.io.FileOutputStream; 014import java.awt.image.BufferedImage; 015 016import javax.imageio.ImageIO; 017import java.awt.Image; 018import java.awt.Graphics; 019/** 020 * Methods to read and write files designed to be 021 * used within other programs. 022 * <p>Note: {@link java.net.SocketTimeoutException} is a subclass of 023 * {@link java.io.IOException}.</p> 024 * <p>Note: Using the {@link URLConnection#setReadTimeout(int) } and 025 * {@link URLConnection#setConnectTimeout(int) } methods should 026 * prevent the methods in this class from hanging.</p> 027 * <p>It looks like the best approach is to rerun the process if an 028 * error occurs. Start with small timeout values and increase them 029 * on each iteration.</p> 030 * @author Bradley Ross 031 */ 032public class FileHelpers 033{ 034 /** 035 * Since all of the methods and fields are static, the constructor 036 * should never be used. 037 */ 038 protected FileHelpers() { ; } 039 /** 040 * Number of milliseconds to wait for a read or 041 * socket operation. 042 * @see #getTimeout() 043 * @see #setTimeout(int) 044 * @see URLConnection#setReadTimeout(int) 045 * @see URLConnection#setConnectTimeout(int) 046 * @deprecated 047 */ 048 protected static int timeout = 10000; 049 /** 050 * Length of time allowed for connect operations. 051 * 052 * @see URLConnection#setConnectTimeout(int) 053 * @see #setConnectTimeout(int) 054 * @see #getConnectTimeout() 055 */ 056 protected static int connectTimeout = 500; 057 /** 058 * Length of time allowed for read operations. 059 * 060 * @see URLConnection#setReadTimeout(int) 061 * @see #setReadTimeout(int) 062 * @see #getReadTimeout() 063 */ 064 protected static int readTimeout = 500; 065 /** 066 * Timeout for entire transfer in milliseconds. 067 * @see #getCombinedTime() 068 * @see #setConnectTimeout(int) 069 */ 070 protected static long combinedTime = 80000; 071 /** 072 * Getter for connectTimeout. 073 * 074 * @see #connectTimeout 075 * @return Timeout value for connect operations 076 */ 077 public static int getConnectTimeout() 078 { return connectTimeout; } 079 /** 080 * Setter for connectTimeout. 081 * 082 * @see #connectTimeout 083 * @param value Value to be used for timeout for socket operations. 084 */ 085 public static void setConnectTimeout(int value) 086 { connectTimeout = value; } 087 /** 088 * Getter for readTimeout. 089 * 090 * @see #readTimeout 091 * @return Timeout value for socket operations 092 */ 093 public static int getReadTimeout() 094 { return readTimeout; } 095 /** 096 * Setter for readTimeout. 097 * 098 * @see #readTimeout 099 * @param value Value to be used for timeout for read operations 100 */ 101 public static void setReadTimeout(int value) 102 { readTimeout = value; } 103 /** 104 * Getter for combinedTime 105 * @return Milliseconds allowed for entire file transfer 106 * @see #combinedTime 107 */ 108 public static long getCombinedTime() 109 { return combinedTime; } 110 /** 111 * Setter for combinedTimeout 112 * @param value Number of milliseconds to be allowed for the entire file transfer 113 * @see #combinedTime 114 */ 115 public static void setCombinedTime(long value) 116 { combinedTime = value; } 117 /** 118 * Setter for timeout. 119 * 120 * @param value Milliseconds to wait for read or socket operation 121 * @see #timeout 122 * @deprecated 123 */ 124 public void setTimeout(int value) 125 { timeout = value; } 126 /** 127 * Getter for timeout 128 * 129 * @return Milliseconds to wait for read or socket operation 130 * @see #timeout 131 * @deprecated 132 */ 133 public int getTimeout() 134 { return timeout; } 135 /** 136 * Determines quantity of diagnostic output to be generated. 137 * @see #getDebugLevel() 138 * @see #setDebugLevel(int) 139 */ 140 protected static int debugLevel = 0; 141 /** 142 * Getter for debugLevel 143 * @see #debugLevel 144 * @return Value of debugLevel 145 */ 146 public static int getDebugLevel() 147 { return debugLevel; } 148 /** 149 * Setter for debugLevel 150 * @see #debugLevel 151 * @param value to be used for debugLevel 152 */ 153 public static void setDebugLevel(int value) 154 { debugLevel = value; } 155 /** 156 * Calculates 2 to the power i as a helper in determining timings 157 * for some of the operations. 158 * @param i Power to which 2 is raised 159 * @return 2 to the power i 160 */ 161 protected static int power(int i) 162 { 163 if (i <= 0) { return 1; } 164 else if (i == 1) { return 2; } 165 else if (i == 2) { return 4; } 166 else if (i > 32) { return Integer.MAX_VALUE; } 167 else 168 { 169 int working = 2; 170 for (int i2 = 1; i2 < i; i2++) 171 { working = working * 2; } 172 return working; 173 } 174 } 175 /** 176 * Reads the contents of a text file into a String object 177 * given the name of the file. 178 * @param name File name 179 * @return Contents of file 180 */ 181 public static String readTextFile(String name) 182 throws java.io.IOException 183 { 184 File inputFile = new File(name); 185 if (!inputFile.exists()) 186 { 187 return (String) null; 188 } 189 FileReader reader = null; 190 StringBuffer working = new StringBuffer(); 191 char[] buffer = new char[4096]; 192 try 193 { 194 reader = new FileReader(inputFile); 195 while (true) 196 { 197 int length = reader.read(buffer, 0, buffer.length); 198 if (length < 0) { break; } 199 working.append(buffer, 0, length); 200 } 201 reader.close(); 202 } 203 catch (java.io.IOException e) 204 { 205 if (Thread.currentThread().isInterrupted()) 206 { 207 System.out.println("*****Interrupted"); 208 Thread.yield(); 209 return (String) null; 210 } 211 System.out.println("Exception encountered " + e.getClass().getName()); 212 System.out.println(e.getMessage()); 213 e.printStackTrace(System.out); 214 /* 215 * Throwing the exception to the calling program added 216 * 06-November-2008. 217 */ 218 throw e; 219 } 220 return new String(working); 221 } 222 /** 223 * Read the contents referenced by a URL into a String 224 * object. 225 * <p>The java.net.URL object required as a parameter is 226 * created by a call of the type 227 * <code>java.net.URL url = 228 * new java.net.URL(urlString)</code> where urlString 229 * is a String object containing the URL identifier.</p> 230 * <p>This should only be used for text files. Results are 231 * unpredictable and probably undesirable when working 232 * with binary files.</p> 233 * 234 * <ul> 235 * <li><p>ftp: <code>ftp://userid:password@host:port/file</code></p> 236 * </li> 237 * <li><p>file: <code>file:// (file name starting with / indicating root)</code></p> 238 * </li> 239 * </ul> 240 * @param address URL of desired contents 241 * @return String 242 */ 243 public static String readTextFile(java.net.URL address) 244 throws java.io.IOException 245 { 246 StringBuffer working = new StringBuffer(); 247 long startTime = System.currentTimeMillis(); 248 long currentTime = System.currentTimeMillis(); 249 long endTime = System.currentTimeMillis() + combinedTime; 250 int totalLength = 0; 251 boolean success = false; 252 int tries = 0; 253 for (int i = 0; i < 4; i++) 254 { 255 tries++; 256 try 257 { 258 URLConnection connection = null; 259 connection = address.openConnection(); 260 connection.setConnectTimeout(connectTimeout * power(i)); 261 connection.setReadTimeout(readTimeout * power(i)); 262 connection.connect(); 263 java.io.FilterInputStream contents = 264 (java.io.FilterInputStream) connection.getContent(); 265 if (debugLevel > 0) 266 { 267 System.out.println("Class is " + contents.getClass().getName()); 268 System.out.println("Superclass is " + 269 contents.getClass().getSuperclass().getName()); 270 } 271 byte[] line = new byte[500]; 272 java.io.BufferedInputStream buffer = new 273 java.io.BufferedInputStream(contents); 274 int charsRead; 275 /* When obtaining the contents, the class of contents is 276 * sun.net.www.content.text.PlainTextInputStream 277 * whose superclass is 278 * java.io.FilterInputStream 279 */ 280 while (true) 281 { 282 charsRead = buffer.read(line, 0, 490); 283 if (charsRead < 0) { break; } 284 // System.out.println("** " + Integer.toString(charsRead) + " **"); 285 working.append(new String(line, 0, charsRead)); 286 totalLength = totalLength + charsRead; 287 currentTime = System.currentTimeMillis(); 288 if (currentTime > endTime) 289 { 290 throw new java.io.IOException("Time limit of " + 291 Long.toString(combinedTime) + " milliseconds exceeded" + 292 " readTextFile(URL)"); 293 } 294 } 295 if (currentTime - startTime > 30000l) 296 { 297 System.out.println(Long.toString(currentTime - startTime) + " milliseconds for " + 298 Integer.toString(totalLength) + " bytes"); 299 } 300 if (debugLevel > 0) 301 { 302 System.out.print(" " + Integer.toString(totalLength) + 303 " bytes "); 304 } 305 success = true; 306 } 307 catch (java.io.IOException e) 308 { 309 if (Thread.currentThread().isInterrupted()) 310 { 311 System.out.println("***** Interrupted"); 312 Thread.yield(); 313 return (String) null; 314 } 315 System.out.println("Exception encountered in readTextFile " + 316 "(Attempt " + Integer.toString(tries) + ") "); 317 System.out.println(" " + e.getClass().getName() + " " + e.getMessage()); 318 if (tries > 4) { throw e; } 319 } 320 if (success) {break; } 321 } 322 if (success && tries > 1) 323 { System.out.println("Success after " + Integer.toString(tries) + " tries"); } 324 return new String(working); 325 } 326 /** 327 * Write the contents of a byte array to a URL as a binary data stream. 328 * <p>It appears that you can write to protocol ftp but not to protocol 329 * file.</p> 330 * @param address URL of destination 331 * @param data Byte array to be sent 332 * @throws java.io.IOException 333 * @throws java.net.SocketTimeoutException 334 * @see java.net.URLConnection 335 */ 336 public static void sendBytes (java.net.URL address, byte[] data) 337 throws java.io.IOException 338 { 339 int tries = 0; 340 boolean success = false; 341 for (int i = 0; i < 4; i++) 342 { 343 URLConnection connection = null; 344 java.io.OutputStream output = null; 345 try 346 { 347 connection = address.openConnection(); 348 connection.setDoInput(false); 349 connection.setDoOutput(true); 350 connection.setReadTimeout(readTimeout * power(i)); 351 connection.setConnectTimeout(connectTimeout * power(i)); 352 showProperties(connection); 353 connection.connect(); 354 output = connection.getOutputStream(); 355 output.write(data); 356 output.close(); 357 success = true; 358 } 359 catch (java.io.IOException e) 360 { 361 if (Thread.currentThread().isInterrupted()) 362 { 363 System.out.println("***** Interrupted"); 364 Thread.yield(); 365 return; 366 } 367 System.out.println("Error in sendBytes: " + e.getClass().getName() + " " + 368 e.getMessage()); 369 } 370 tries++; 371 if (success) { break; } 372 } 373 if (!success) 374 { 375 System.out.println("Failure after " + Integer.toString(tries) + " tries"); 376 throw new IOException("Failure after " + Integer.toString(tries) + " tries"); 377 } 378 if (success && tries > 1) 379 { 380 System.out.println("Success after " + Integer.toString(tries) + " tries"); 381 } 382 } 383 /** 384 * Write the contents of a file to a URL, passing the data as 385 * a byte stream (binary data). 386 * @param address URL of destination 387 * @param data File object containing data to be sent 388 * @throws java.io.IOException 389 */ 390 public static void sendBytes (java.net.URL address, java.io.File data) 391 throws java.io.IOException 392 { 393 int tries = 0; 394 boolean success = false; 395 for (int i = 0; i < 4; i++) 396 { 397 long startTime = System.currentTimeMillis(); 398 long currentTime = startTime; 399 long endTime = startTime + combinedTime; 400 URLConnection connection = null; 401 java.io.FileInputStream input = null; 402 java.io.OutputStream output = null; 403 byte[] buffer = new byte[32768]; 404 int byteCounter = 0; 405 int readCounter = 0; 406 try 407 { 408 connection = address.openConnection(); 409 connection.setDoInput(false); 410 connection.setDoOutput(true); 411 /* 412 * I changed the multiplier from (i+1) to 413 * power(i) 414 */ 415 connection.setReadTimeout(readTimeout * power(i)); 416 connection.setConnectTimeout(connectTimeout * power(i)); 417 showProperties(connection); 418 connection.connect(); 419 output = connection.getOutputStream(); 420 input = new java.io.FileInputStream(data); 421 while (true) 422 { 423 int length = input.read(buffer); 424 if (length < 0) { break; } 425 output.write(buffer, 0, length); 426 byteCounter = byteCounter + length; 427 readCounter++; 428 // Thread.yield(); 429 if (System.currentTimeMillis() > endTime) 430 { 431 throw new java.io.IOException("Time limit of " + 432 Long.toString(combinedTime) + 433 " milliseconds exceeded in sendBytes(URL, File)"); 434 } 435 } 436 currentTime = System.currentTimeMillis(); 437 if (currentTime - startTime > 30000l) 438 { 439 System.out.println("sendBytes(URL, File) required " + Long.toString(currentTime - startTime) + 440 " milliseconds to process " + data.getCanonicalPath() + " : " + 441 Integer.toString(byteCounter) + " bytes in " + Integer.toString(readCounter) + 442 " reads"); 443 String name = address.getFile(); 444 /* 445 * It is necessary to remove the portion of the name following the semicolon since the 446 * URL methods include the type designation (;type=i or ;type=a) with the name portion of the 447 * URL. 448 */ 449 if (name.indexOf(";") > 0) 450 { 451 name = name.substring(0, name.indexOf(";")); 452 } 453 System.out.println("Guessed MIME type for " + name + 454 " is " + URLConnection.guessContentTypeFromName(name)); 455 } 456 input.close(); 457 output.close(); 458 success = true; 459 } 460 catch (java.io.IOException e) 461 { 462 if (Thread.interrupted()) { Thread.yield(); return; } 463 System.out.println("Error in sendBytes: " + e.getClass().getName() + " " + 464 e.getMessage()); 465 } 466 tries++; 467 if (success) { break; } 468 } 469 if (!success) 470 { 471 System.out.println("Failure after " + Integer.toString(tries) + " tries"); 472 throw new IOException("Failure after " + Integer.toString(tries) + " tries"); 473 } 474 if (success && tries > 1) 475 { 476 System.out.println("Success after " + Integer.toString(tries) + " tries"); 477 } 478 } 479 /** 480 * Send the contents of an InputStream to a File. 481 * @param output File object for output. 482 * @param input InputStream for input. 483 */ 484 public static void sendBytes (File output, InputStream input) 485 { 486 byte buffer[] = new byte[65536]; 487 int charsRead = 0; 488 int totalChars = 0; 489 try 490 { 491 FileOutputStream sender = new FileOutputStream(output); 492 while (true) 493 { 494 charsRead = input.read(buffer); 495 496 if (charsRead < 0) 497 { 498 break; 499 } 500 totalChars = totalChars + charsRead; 501 sender.write (buffer, 0, charsRead); 502 System.out.println(Integer.toString(charsRead) + " " + Integer.toString(totalChars)); 503 } 504 sender.close(); 505 } 506 catch (FileNotFoundException e) 507 { 508 System.out.println(e.getClass().getName() + " " + e.getMessage()); 509 } 510 catch (IOException e) 511 { 512 System.out.println(e.getClass().getName() + " " + e.getMessage()); 513 } 514 } 515 /** 516 * Read the contents of a URL into a file, passing the 517 * data as byte (binary) stream. 518 * 519 * <p>In case of failure, the algorithm retries with 520 * increased values of connectTimeout and 521 * readTimeout.</p> 522 * <p>This modification may eventually be added to the 523 * other methods.</p> 524 * @param url Location of data to be read 525 * @param file File where data is to be written 526 * @see URLConnection#setReadTimeout(int) 527 * @see URLConnection#setConnectTimeout(int) 528 * @throws java.io.IOException 529 */ 530 public static void getBytes(URL url, File file) 531 throws java.io.IOException 532 { 533 boolean success = false; 534 int tries = 0; 535 int totalLength = 0; 536 URLConnection connection = null; 537 java.io.FileOutputStream output = null; 538 java.io.InputStream input = null; 539 byte[] buffer = new byte[32768]; 540 long startTime = System.currentTimeMillis(); 541 long endTime = startTime + combinedTime; 542 long currentTime = System.currentTimeMillis(); 543 for (int i = 0; i < 4; i++) 544 { 545 if (output != null) 546 { 547 output.close(); 548 output = null; 549 } 550 if (input != null) 551 { 552 input = null; 553 } 554 if (connection != null) 555 { 556 connection = null; 557 } 558 output = null; 559 input = null; 560 try { 561 connection = url.openConnection(); 562 connection.setDoInput(true); 563 connection.setDoOutput(false); 564 connection.setReadTimeout(readTimeout * power(i)); 565 connection.setConnectTimeout(connectTimeout * power(i)); 566 showProperties(connection); 567 connection.connect(); 568 input = connection.getInputStream(); 569 while (true) 570 { 571 /* 572 * The read statement blocks until there 573 * are characters available to be read. 574 * 575 * I thought that using 576 * URLConnection.setReadTimeout 577 * would result in an exception if the 578 * time out was exceeded but it doesn't seem 579 * to be happening. 580 */ 581 int length = input.read(buffer); 582 if (length < 0) 583 { 584 break; 585 } 586 if (output == null) { 587 output = new java.io.FileOutputStream(file); 588 } 589 output.write(buffer, 0, length); 590 totalLength = totalLength + length; 591 Thread.yield(); 592 if (debugLevel > 0) 593 { 594 System.out.print("*"); 595 } 596 currentTime = System.currentTimeMillis(); 597 if (currentTime > endTime) { 598 throw new java.io.IOException("Time limit of " 599 + Long.toString(combinedTime) 600 + " milliseconds exceeded " 601 + "in getBytes(URL,File)"); 602 } 603 } /* End of while loop */ 604 605 input.close(); 606 if (output != null) 607 { 608 output.close(); 609 } 610 success = true; 611 } 612 catch (java.io.IOException e) 613 { 614 if (Thread.currentThread().isInterrupted()) 615 { 616 System.out.println("***** Interrupted"); 617 Thread.yield(); 618 return; 619 } 620 if (i == 3 || debugLevel > 0) 621 { 622 System.out.println("Error in getBytes: " 623 + e.getClass().getName() + " " + e.getMessage()); 624 System.out.println(" Number of bytes moved: " 625 + Integer.toString(totalLength)); 626 } 627 if (i == 3) 628 { 629 throw e; 630 } 631 } 632 tries = i + 1; 633 if (success) { break; } 634 } 635 if (!success) 636 { 637 System.out.println("Failure after " + Integer.toString(tries) + " tries"); 638 } 639 else if (success && tries > 1 && debugLevel > 0) 640 { 641 System.out.println("Success after " + Integer.toString(tries) + " tries"); 642 } 643 if (debugLevel > 0) 644 { System.out.print(" " + Integer.toString(totalLength) + " bytes "); } 645 if (currentTime - startTime > 30000) 646 { 647 System.out.println(Long.toString(currentTime - startTime) + 648 " milliseconds for " + Integer.toString(totalLength) + 649 " bytes"); 650 } 651 } 652 /** 653 * Read the contents of a a file and then sends 654 * the data to a OutputStream object. 655 * 656 * @param input File containing data to be written 657 * @param output OutputStream object where data is to be written 658 * @throws java.io.IOException 659 * @see File 660 */ 661 public static void getBytes(File input, OutputStream output) 662 throws java.io.IOException 663 { 664 FileInputStream reader = new FileInputStream(input); 665 int totalLength = 0; 666 byte[] buffer = new byte[4096]; 667 long startTime = System.currentTimeMillis(); 668 long currentTime = startTime; 669 long endTime = startTime + combinedTime; 670 if (debugLevel > 1) 671 { 672 System.out.println("getBytes(File,OutputStream: " + input.getName() + " exists: " + 673 Boolean.toString(input.exists())); 674 System.out.println("getBytes(File,OutputStream): "); 675 } 676 try 677 { 678 while (true) 679 { 680 /* 681 * The read statement blocks until there 682 * are characters available to be read. 683 * 684 * I thought that using 685 * URLConnection.setReadTimeout 686 * would result in an exception if the 687 * time out was exceeded but it doesn't seem 688 * to be happening. 689 */ 690 int length = reader.read(buffer); 691 if (debugLevel > 1) 692 { 693 System.out.println(Integer.toString(length) + " bytes read"); 694 } 695 if (length < 0) { break; } 696 697 output.write(buffer, 0, length); 698 totalLength = totalLength + length; 699 Thread.yield(); 700 if (debugLevel > 0) { System.out.print("*"); } 701 currentTime = System.currentTimeMillis(); 702 if (currentTime > endTime) 703 { 704 reader.close(); 705 throw new java.io.IOException("Time limit of " + 706 Long.toString(combinedTime) + 707 " milliseconds exceeded in getBytes(File, OutputStream)"); 708 } 709 } 710 if (debugLevel > 0) 711 { System.out.println("Total of " + Integer.toString(totalLength) + " bytes processed "); } 712 if (currentTime - startTime > 30000) 713 { 714 System.out.println(Long.toString(currentTime - startTime) + " milliseconds for " + 715 Integer.toString(totalLength) + " bytes"); 716 } 717 } 718 catch (java.io.IOException e) 719 { 720 if (Thread.currentThread().isInterrupted()) 721 { 722 System.out.println("***** Interrupted"); 723 Thread.yield(); 724 return; 725 } 726 System.out.println("Error in getBytes: " + e.getClass().getName() + " " + 727 e.getMessage()); 728 System.out.println("Number of bytes moved: " + 729 Integer.toString(totalLength)); 730 throw e; 731 } 732 reader.close(); 733 } 734 /** 735 * Read the contents of a a URL and then sends 736 * the data to a OutputStream object. 737 * 738 * @param url URL of item to be copied 739 * @param output OutputStream object where data is to be written 740 * @throws java.io.IOException 741 * 742 */ 743 public static void getBytes(URL url, OutputStream output) 744 throws IOException 745 { 746 boolean success = false; 747 int tries = 0; 748 int totalLength = 0; 749 URLConnection connection = null; 750 java.io.InputStream input = null; 751 byte[] buffer = new byte[32768]; 752 long startTime = System.currentTimeMillis(); 753 long endTime = startTime + combinedTime; 754 long currentTime = System.currentTimeMillis(); 755 for (int i = 0; i < 4; i++) 756 { 757 if (input != null) 758 { 759 input = null; 760 } 761 if (connection != null) 762 { 763 connection = null; 764 } 765 input = null; 766 try { 767 connection = url.openConnection(); 768 connection.setDoInput(true); 769 connection.setDoOutput(false); 770 connection.setReadTimeout(readTimeout * power(i)); 771 connection.setConnectTimeout(connectTimeout * power(i)); 772 showProperties(connection); 773 connection.connect(); 774 input = connection.getInputStream(); 775 776 while (true) { 777 /* 778 * The read statement blocks until there 779 * are characters available to be read. 780 * 781 * I thought that using 782 * URLConnection.setReadTimeout 783 * would result in an exception if the 784 * time out was exceeded but it doesn't seem 785 * to be happening. 786 */ 787 int length = input.read(buffer); 788 if (length < 0) { 789 break; 790 } 791 792 output.write(buffer, 0, length); 793 totalLength = totalLength + length; 794 Thread.yield(); 795 if (debugLevel > 0) { 796 System.out.print("*"); 797 } 798 currentTime = System.currentTimeMillis(); 799 if (currentTime > endTime) { 800 throw new java.io.IOException("Time limit of " 801 + Long.toString(combinedTime) 802 + " milliseconds exceeded " 803 + "in getBytes(URL,File)"); 804 } 805 } /* End of while loop */ 806 807 input.close(); 808 if (output != null) 809 { 810 output.close(); 811 } 812 success = true; 813 } 814 catch (java.io.IOException e) 815 { 816 if (Thread.currentThread().isInterrupted()) { 817 System.out.println("***** Interrupted"); 818 Thread.yield(); 819 return; 820 } 821 System.out.println("Error in getBytes: " 822 + e.getClass().getName() + " " + e.getMessage()); 823 System.out.println(" Number of bytes moved: " 824 + Integer.toString(totalLength)); 825 if (i == 3) 826 { 827 throw e; 828 } 829 } 830 tries = i + 1; 831 if (success) { break; } 832 } 833 if (!success) 834 { 835 System.out.println("Failure after " + Integer.toString(tries) + " tries"); 836 } 837 else if (success && tries > 1) 838 { 839 System.out.println("Success after " + Integer.toString(tries) + " tries"); 840 } 841 if (debugLevel > 0) 842 { System.out.print(" " + Integer.toString(totalLength) + " bytes "); } 843 if (currentTime - startTime > 30000) 844 { 845 System.out.println(Long.toString(currentTime - startTime) + 846 " milliseconds for " + Integer.toString(totalLength) + 847 " bytes"); 848 } 849 } 850 /** 851 * Copy a file. 852 * 853 * 854 * @param input File object for file to be copied 855 * @param output File object for copy of file to be created 856 * @throws IOException 857 * @see FileOutputStream 858 */ 859 public static void copyFile (File input, File output) 860 throws IOException 861 { 862 boolean test; 863 if (!input.exists()) 864 { 865 throw new IOException("copyFile: input file does not exist"); 866 } 867 if (!input.canRead()) 868 { 869 throw new IOException("copyFile: unable to read input file"); 870 } 871 if (!output.getParentFile().exists()) 872 { 873 System.out.println("Creating directory " + output.getParent()); 874 fixDirs(output); 875 } 876 if (!output.exists()) 877 { 878 test = output.createNewFile(); 879 if (!test) 880 { 881 System.out.println("Error creating new file"); 882 throw new IOException("Unable to create new file"); 883 } 884 } 885 if (!output.canWrite()) 886 { 887 throw new IOException("copyFile: unable to write output file"); 888 } 889 if (debugLevel > 1) 890 { 891 System.out.println("copyFile(File,File): Starting copyFile"); 892 System.out.println("*** " + input.getName() + " exists: " + Boolean.toString(input.exists())); 893 System.out.println("*** " + input.getCanonicalPath()); 894 System.out.println("*** length: " + Long.toString(input.length())); 895 System.out.println("*** canRead(): " + Boolean.toString(input.canRead())); 896 System.out.println("*** " + output.getName() + " exists: " + Boolean.toString(output.exists())); 897 } 898 FileOutputStream outputStream = new FileOutputStream(output); 899 getBytes(input, outputStream); 900 outputStream.close(); 901 } 902 /** 903 * Copy a file. 904 * 905 * @param inputFileName Name of file to be copied 906 * @param outputFileName Name of copy of file to be created 907 * @throws IOException 908 * @see bradleyross.library.helpers.tests.TestCopyFile 909 */ 910 public static void copyFile (String inputFileName, String outputFileName) 911 throws IOException 912 { 913 File input = new File(inputFileName); 914 File output = new File(outputFileName); 915 copyFile(input, output); 916 } 917 /** 918 * Checks to see if directories for a file exist, and then 919 * creates directories as appropriate. 920 * @param newFile File object to be created 921 * @throws java.io.IOException 922 * @see File 923 */ 924 public static void fixDirs(File newFile) 925 throws java.io.IOException 926 { 927 try 928 { 929 File directory = newFile.getParentFile(); 930 if (directory == null) { return; } 931 if (directory.exists()) 932 { return; } 933 else 934 { 935 directory.mkdirs(); 936 return; 937 } 938 } 939 catch (Exception e) 940 { 941 System.out.println("Error in fixDirs: unable to create directories " + 942 "for " + newFile.toString()); 943 System.out.println(e.getClass().getName() + " " + 944 e.getMessage()); 945 e.printStackTrace(System.out); 946 throw new java.io.IOException("Unable to create directories for " + 947 newFile.toString() + " " + 948 e.getClass().getName() + " " + e.getMessage()); 949 } 950 } 951 952 /** 953 * Checks to see if directories for a file exist, and then 954 * creates directories as appropriate. 955 * @param name Name of file or directory to be created 956 * @throws java.io.IOException 957 * @see File 958 */ 959 public static void fixDirs(String name) 960 throws IOException 961 { 962 try 963 { 964 File newFile = new File(name); 965 File directory = newFile.getParentFile(); 966 if (directory == null) { return; } 967 if (directory.exists()) 968 { return; } 969 else 970 { 971 directory.mkdirs(); 972 return; 973 } 974 } 975 catch (Exception e) 976 { 977 System.out.println("Error in fixDirs: unable to create directories " + 978 "for " + name); 979 System.out.println(e.getClass().getName() + " " + 980 e.getMessage()); 981 e.printStackTrace(System.out); 982 throw new java.io.IOException("Unable to create directories for " + 983 e.getClass().getName() + " " + e.getMessage()); 984 } 985 } 986 /** 987 * Send properties for connection to System.out 988 * <p>This is intended for diagnostic purposes. 989 * @param connection Connection object 990 */ 991 public static void showProperties(URLConnection connection) 992 { 993 if (debugLevel <= 0) { return; } 994 Map<String,List<String>> properties = connection.getRequestProperties(); 995 System.out.println("There are " + Integer.toString(properties.size()) + " properties"); 996 Object keySet[] = properties.keySet().toArray(); 997 for (int i = 0; i < keySet.length; i++) 998 { 999 System.out.println((String) keySet[i]); 1000 } 1001 } 1002 /** 1003 * This is a test driver to check out the copyFile method. 1004 * 1005 * @param args Names of original file and copy to be created 1006 */ 1007 public static void main (String[] args) 1008 { 1009 String test = "1, 2, alpha, beta, gamma , ,,,"; 1010 String tokens[] = lineSplitterCommas(test); 1011 System.out.println("There are " + Integer.toString(tokens.length) + " items"); 1012 for (int i = 0; i < tokens.length; i++) 1013 { 1014 System.out.print("*" + tokens[i] + " "); 1015 } 1016 System.out.println(); 1017 /** 1018 if (args.length < 2) 1019 { 1020 System.out.println("Not enough arguments"); 1021 } 1022 try 1023 { 1024 System.out.println("Copying " + args[0] + " to " + args[1]); 1025 copyFile(args[0], args[1]); 1026 } 1027 catch (IOException e) 1028 { 1029 System.out.println("Error in running driver"); 1030 System.out.println(e.getClass().getName() + " " + 1031 e.getMessage()); 1032 e.printStackTrace(); 1033 } 1034 */ 1035 } 1036 /** 1037 * Split a line into tokens using spaces as the field separators. 1038 * 1039 * <p>This method can be used as an example of processing regular 1040 * expressions in Java.</p> 1041 * @param input Line to be split into tokens 1042 * @return Array of strings containing the tokens. 1043 */ 1044 public static String[] lineSplitterSpaces (String input) 1045 { 1046 java.util.regex.Pattern pattern = java.util.regex.Pattern.compile ("\\s+"); 1047 java.util.regex.Matcher matcher = pattern.matcher(input.trim()); 1048 String result = matcher.replaceAll(" "); 1049 return result.split(" "); 1050 } 1051 /** 1052 * Split a line into tokens using commas as the field separators. 1053 * 1054 * <p>The space is suffixed to the input parameter because the system 1055 * doesn't seem to recognize a comma as the last character in the 1056 * string as signifying a new token.</p> 1057 * @param input Line to be split into tokens 1058 * @return Array of strings containing the tokens. 1059 */ 1060 public static String[] lineSplitterCommas (String input) 1061 { 1062 String tokens[] = (input + " ").split(","); 1063 for (int i = 0; i < tokens.length; i ++) 1064 { 1065 tokens[i] = tokens[i].trim(); 1066 } 1067 return tokens; 1068 } 1069 /** 1070 * Create a file containing a thumbnail image from another file. 1071 * @param inputFile Name of file to be read 1072 * @param outputFile Name of file to be generated 1073 * @param sizeX Width of generated image in pixels 1074 * @param sizeY Height of generated image in pixels 1075 * @see BufferedImage 1076 * @see javax.imageio.ImageIO 1077 * @see java.awt.image.RenderedImage 1078 */ 1079 public static void thumbnail(String inputFile, String outputFile, int sizeX, int sizeY) throws IOException { 1080 thumbnail(new File(inputFile), new File(outputFile), sizeX, sizeY); 1081 } 1082 /** 1083 * Create a file containing a thumbnail image from another file. 1084 * @param input file to be read 1085 * @param output file to be generated 1086 * @param sizeX Width of generated image in pixels 1087 * @param sizeY Height of generated image in pixels 1088 * @see BufferedImage 1089 * @see javax.imageio.ImageIO 1090 * @see java.awt.image.RenderedImage 1091 */ 1092 public static void thumbnail(File input, File output, int sizeX, int sizeY) throws IOException 1093 { 1094 if (debugLevel > 2) 1095 { 1096 System.out.println("Arguments: " + input.getCanonicalPath() + ", " + output.getCanonicalPath() + ", " + 1097 Integer.toString(sizeX) + ", " + Integer.toString(sizeY)); 1098 } 1099 Integer targetX = 0; 1100 Integer targetY = 0; 1101 if (sizeX <= 0 && sizeY <= 0) 1102 { 1103 throw new IOException("Either target width or target height must be positive"); 1104 } 1105 else if (sizeX == 0 || sizeY == 0) 1106 { 1107 throw new IOException("Zero not acceptable for target width or target height"); 1108 } 1109 String inputFileName = input.getCanonicalPath(); 1110 BufferedImage image = null; 1111 BufferedImage thumb = null; 1112 Image intermediate = null; 1113 String format = null; 1114 String suffix = null; 1115 FileOutputStream outputStream = null; 1116 String outputName = output.getName(); 1117 suffix = outputName.substring(outputName.lastIndexOf(".") + 1); 1118 if (suffix == null) 1119 { 1120 throw new IOException("No suffix found for output file " + 1121 outputName + " (null value)"); 1122 } 1123 else if (suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("jpeg")) 1124 { format = "jpeg"; } 1125 else if (suffix.equalsIgnoreCase("png")) 1126 { format = "png"; } 1127 else if (suffix.equalsIgnoreCase("gif")) 1128 { format = "gif"; } 1129 else 1130 { throw new IOException("Unable to process suffix " + suffix + 1131 " for file " + outputName); } 1132 try 1133 { 1134 image = javax.imageio.ImageIO.read(new FileInputStream(input)); 1135 } 1136 catch (FileNotFoundException e) 1137 { 1138 throw new IOException("Unable to find file " + inputFileName + " " + 1139 e.getMessage()); 1140 } 1141 catch (IOException e) 1142 { 1143 throw new IOException("Unexpected error while reading file " + inputFileName + " " + 1144 e.getMessage()); 1145 } 1146 if (sizeX <= 0 || sizeY <= 0) 1147 { 1148 if (debugLevel > 2) 1149 { 1150 System.out.println("Must adjust one parameter"); 1151 } 1152 Double ratio = (double) image.getWidth() / (double) image.getHeight(); 1153 if (sizeX < 0) 1154 { 1155 targetY = sizeY; 1156 targetX = (int) (Math.floor((double) sizeY * ratio)); 1157 } 1158 else if (sizeY < 0) 1159 { 1160 targetX = sizeX; 1161 targetY = (int) (Math.floor((double) sizeX / ratio)); 1162 } 1163 } 1164 else if (sizeX > 0 && sizeY > 0) 1165 { 1166 targetX = sizeX; 1167 targetY = sizeY; 1168 } 1169 intermediate = image.getScaledInstance(targetX, targetY, BufferedImage.SCALE_FAST); 1170 thumb = new BufferedImage(targetX, targetY, BufferedImage.TYPE_INT_RGB); 1171 Graphics g = thumb.createGraphics(); 1172 g.drawImage(intermediate, 0, 0, null); 1173 outputStream = new FileOutputStream(output); 1174 ImageIO.write(thumb, format, outputStream); 1175 } 1176 /** 1177 * Makes file with thumbnail image 1178 * @param input Input file 1179 * @param output Output file 1180 * @param size Height and width of output image in pixels 1181 * @throws IOException 1182 */ 1183 public static void thumbnail(String input, String output, int size) throws IOException 1184 { 1185 thumbnail(new File(input), new File(output), size, size); 1186 } 1187 /** 1188 * Makes file with thumbnail image 1189 * @param input Input file 1190 * @param output Output file 1191 * @throws IOException 1192 */ 1193 public static void thumbnail(String input, String output) throws IOException 1194 { 1195 thumbnail(new File(input), new File(output), 150, 150); 1196 } 1197}