Mega Code Archive

 
Categories / Java / File Input Output
 

BGrep

/*  * Copyright (c) 2004 David Flanagan.  All rights reserved.  * This code is from the book Java Examples in a Nutshell, 3nd Edition.  * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.  * You may study, use, and modify it for any non-commercial purpose,  * including teaching and use in open-source projects.  * You may distribute it non-commercially as long as you retain this notice.  * For a commercial use license, or to purchase the book,   * please visit http://www.davidflanagan.com/javaexamples3.  */ //package je3.nio; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /**  * BGrep: a regular expression search utility, like Unix grep, but  * block-oriented instead of line-oriented. For any match found, the filename  * and character position within the file (note: not the line number) are  * printed along with the text that matched.  *   * Usage: java je3.nio.BGrep [options] <pattern> <files>...  *   * Options: -e <encoding> specifies and encoding. UTF-8 is the default -i  * enables case-insensitive matching. Use -s also for non-ASCII text -s enables  * strict (but slower) processing of non-ASCII characters  *   * This program requires that each file to be searched fits into main memory,  * and so does not work with extremely large files.  */ public class BGrep {   public static void main(String[] args) {     String encodingName = "UTF-8"; // Default to UTF-8 encoding     int flags = Pattern.MULTILINE; // Default regexp flags     try { // Fatal exceptions are handled after this try block       // First, process any options       int nextarg = 0;       while (args[nextarg].charAt(0) == '-') {         String option = args[nextarg++];         if (option.equals("-e")) {           encodingName = args[nextarg++];         } else if (option.equals("-i")) { // case-insensitive matching           flags |= Pattern.CASE_INSENSITIVE;         } else if (option.equals("-s")) { // Strict Unicode processing           flags |= Pattern.UNICODE_CASE; // case-insensitive Unicode           flags |= Pattern.CANON_EQ; // canonicalize Unicode         } else {           System.err.println("Unknown option: " + option);           usage();         }       }       // Get the Charset for converting bytes to chars       Charset charset = Charset.forName(encodingName);       // Next argument must be a regexp. Compile it to a Pattern object       Pattern pattern = Pattern.compile(args[nextarg++], flags);       // Require that at least one file is specified       if (nextarg == args.length)         usage();       // Loop through each of the specified filenames       while (nextarg < args.length) {         String filename = args[nextarg++];         CharBuffer chars; // This will hold complete text of the file         try { // Handle per-file errors locally           // Open a FileChannel to the named file           FileInputStream stream = new FileInputStream(filename);           FileChannel f = stream.getChannel();           // Memory-map the file into one big ByteBuffer. This is           // easy but may be somewhat inefficient for short files.           ByteBuffer bytes = f.map(FileChannel.MapMode.READ_ONLY, 0, f.size());           // We can close the file once it is is mapped into memory.           // Closing the stream closes the channel, too.           stream.close();           // Decode the entire ByteBuffer into one big CharBuffer           chars = charset.decode(bytes);         } catch (IOException e) { // File not found or other problem           System.err.println(e); // Print error message           continue; // and move on to the next file         }         // This is the basic regexp loop for finding all matches in a         // CharSequence. Note that CharBuffer implements CharSequence.         // A Matcher holds state for a given Pattern and text.         Matcher matcher = pattern.matcher(chars);         while (matcher.find()) { // While there are more matches           // Print out details of the match           System.out.println(filename + ":" + // file name               matcher.start() + ": " + // character pos               matcher.group()); // matching text         }       }     }     // These are the things that can go wrong in the code above     catch (UnsupportedCharsetException e) { // Bad encoding name       System.err.println("Unknown encoding: " + encodingName);     } catch (PatternSyntaxException e) { // Bad pattern       System.err.println("Syntax error in search pattern:\n" + e.getMessage());     } catch (ArrayIndexOutOfBoundsException e) { // Wrong number of arguments       usage();     }   }   /** A utility method to display invocation syntax and exit. */   public static void usage() {     System.err.println("Usage: java BGrep [-e <encoding>] [-i] [-s]" + " <pattern> <filename>...");     System.exit(1);   } }