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