差异:文本文件差异工具 : 文件命令 « 文件输入输出 « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
Java » 文件输入输出 » 文件命令屏幕截图 
差异:文本文件差异工具
差异:文本文件差异工具


/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 
 * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */
// Diff -- text file difference utility.
// See full docu-comment at beginning of Diff class.

// $Id: Diff.java,v 1.6 2004/02/09 03:34:05 ian Exp $

import java.io.*;

/** This is the info kept per-file.     */
class fileInfo {    

  static final int MAXLINECOUNT = 20000;

  DataInputStream file;  /* File handle that is open for read.  */
  public int maxLine;  /* After input done, # lines in file.  */
  node symbol[]/* The symtab handle of each line. */
  int other[]/* Map of line# to line# in other file */
                                /* ( -1 means don't-know ).            */
        /* Allocated AFTER the lines are read. */

  /**
   * Normal constructor with one filename; file is opened and saved.
   */
  fileInfoString filename ) {
    symbol = new node MAXLINECOUNT+];
    other  = null;    // allocated later!
    try {
      file = new DataInputStream(
        new FileInputStreamfilename));
    catch (IOException e) {
        System.err.println("Diff can't read file " +
        filename );
        System.err.println("Error Exception was:" + e );
        System.exit(1);
    }
  }
  // This is done late, to be same size as # lines in input file.
  void alloc() {
    other  = new int[symbol.length + 2];
  }
};

/**
 * diff         Text file difference utility.
 * ----         Copyright 1987, 1989 by Donald C. Lindsay,
 *              School of Computer Science,  Carnegie Mellon University.
 *              Copyright 1982 by Symbionics.
 *              Use without fee is permitted when not for direct commercial
 *              advantage, and when credit to the source is given. Other uses
 *              require specific permission.
 *
 * Converted from C to Java by Ian F. Darwin, http://www.darwinsys.com/, January, 1997.
 * Copyright 1997, Ian F. Darwin.
 *
 * Conversion is NOT FULLY TESTED.
 *
 * USAGE:      diff oldfile newfile
 *
 * This program assumes that "oldfile" and "newfile" are text files.
 * The program writes to stdout a description of the changes which would
 * transform "oldfile" into "newfile".
 *
 * The printout is in the form of commands, each followed by a block of
 * text. The text is delimited by the commands, which are:
 *
 *    DELETE AT n
 *         ..deleted lines
 *
 *    INSERT BEFORE n
 *         ..inserted lines
 *
 *    n MOVED TO BEFORE n
 *         ..moved lines
 *
 *    n CHANGED FROM
 *         ..old lines
 *    CHANGED TO
 *         ..newer lines
 *
 * The line numbers all refer to the lines of the oldfile, as they are
 *    numbered before any commands are applied.
 * The text lines are printed as-is, without indentation or prefixing. The
 *    commands are printed in upper case, with a prefix of ">>>>", so that
 *    they will stand out. Other schemes may be preferred.
 * Files which contain more than MAXLINECOUNT lines cannot be processed.
 *    This can be fixed by changing "symbol" to a Vector.
 * The algorithm is taken from Communications of the ACM, Apr78 (21, 4, 264-),
 *    "A Technique for Isolating Differences Between Files."
 *    Ignoring I/O, and ignoring the symbol table, it should take O(N) time.
 *    This implementation takes fixed space, plus O(U) space for the symbol
 *    table (where U is the number of unique lines). Methods exist to change
 *    the fixed space to O(N) space.
 * Note that this is not the only interesting file-difference algorithm. In
 *    general, different algorithms draw different conclusions about the
 *    changes that have been made to the oldfile. This algorithm is sometimes
 *    "more right", particularly since it does not consider a block move to be 
 *    an insertion and a (separate) deletion. However, on some files it will be
 *    "less right". This is a consequence of the fact that files may contain
 *    many identical lines (particularly if they are program source). Each
 *    algorithm resolves the ambiguity in its own way, and the resolution
 *    is never guaranteed to be "right". However, it is often excellent.
 * This program is intended to be pedagogic.  Specifically, this program was
 *    the basis of the Literate Programming column which appeared in the
 *    Communications of the ACM (CACM), in the June 1989 issue (32, 6,
 *    740-755).
 * By "pedagogic", I do not mean that the program is gracefully worded, or
 *    that it showcases language features or its algorithm. I also do not mean
 *    that it is highly accessible to beginners, or that it is intended to be
 *    read in full, or in a particular order. Rather, this program is an
 *    example of one professional's style of keeping things organized and
 *    maintainable.
 * The program would be better if the "print" variables were wrapped into
 *    a struct. In general, grouping related variables in this way improves
 *    documentation, and adds the ability to pass the group in argument lists.
 * This program is a de-engineered version of a program which uses less
 *    memory and less time.  The article points out that the "symbol" arrays
 *    can be implemented as arrays of pointers to arrays, with dynamic
 *    allocation of the subarrays.  (In C, macros are very useful for hiding 
 *    the two-level accesses.) In Java, a Vector would be used. This allows an
 *    extremely large value for MAXLINECOUNT, without dedicating fixed arrays.
 *    (The "other" array can be allocated after the input phase, when the exact
 *    sizes are known.) The only slow piece of code is the "strcmp" in the tree
 *    descent: it can be speeded up by keeping a hash in the tree node, and
 *    only using "strcmp" when two hashes happen to be equal.
 *
 * Change Log
 * ----------
 *  1Jan97 Ian F. Darwin: first working rewrite in Java, based entirely on
 *   D.C.Lindsay's reasonable C version.
 *  Changed comments from /***************** to /**, shortened, added
 *  whitespace, used tabs more, etc.
 *  6jul89 D.C.Lindsay, CMU: fixed portability bug. Thanks, Gregg Wonderly.
 *         Just changed "char ch" to "int ch". 
 *         Also added comment about way to improve code.
 * 10jun89 D.C.Lindsay, CMU: posted version created.
 *         Copyright notice changed to ACM style, and Dept. is now School.
 *         ACM article referenced in docn.
 * 26sep87 D.C.Lindsay, CMU: publication version created.
 *         Condensed all 1982/83 change log entries.
 *         Removed all command line options, and supporting code. This 
 *         simplified the input code (no case reduction etc). It also
 *         simplified the symbol table, which was capable of remembering
 *         offsets into files (instead of strings), and trusting (!) hash
 *         values to be unique.
 *         Removed dynamic allocation of arrays: now fixed static arrays.
 *         Removed speed optimizations in symtab package.
 *         Removed string compression/decompression code.
 *         Recoded to Unix standards from old Lattice/MSDOS standards.
 *         (This affected only the #include's and the IO.)
 *         Some renaming of variables, and rewording of comments.
 * 1982/83 D.C.Lindsay, Symbionics: created.
 *
 @author  Ian F. Darwin, Java version
 @version  Java version 0.9, 1997
 @author  D. C. Lindsay, C version (1982-1987)
 *
 */
public class Diff {

  /** block len > any possible real block len */
  final int UNREAL=Integer.MAX_VALUE;

  /** Keeps track of information about file1 and file2 */
  fileInfo oldinfo, newinfo;

  /** blocklen is the info about found blocks. It will be set to 0, except
   * at the line#s where blocks start in the old file. At these places it
   * will be set to the # of lines in the block. During printout ,
   * this # will be reset to -1 if the block is printed as a MOVE block
   * (because the printout phase will encounter the block twice, but
   * must only print it once.)
   * The array declarations are to MAXLINECOUNT+2 so that we can have two
   * extra lines (pseudolines) at line# 0 and line# MAXLINECOUNT+1
   * (or less).
   */
  int blocklen[];

  /**
   * main - entry point when used standalone.
   * NOTE: no routines return error codes or throw any local
   * exceptions. Instead, any routine may complain
   * to stderr and then exit with error to the system.
   */
  public static void main(String argstrings[])
  {
    if argstrings.length != ) {
      System.err.println("Usage: diff oldfile newfile" );
      System.exit(1);
    }
    Diff d = new Diff();
    d.doDiff(argstrings[0], argstrings[1]);
    return;
  }

  /** Construct a Diff object. */
  Diff() {
  }

  /** Do one file comparison. Called with both filenames. */
  public void doDiff(String oldFile, String newFile) {
    println">>>> Difference of file \"" + oldFile + 
      "\" and file \"" + newFile + "\".\n");
    oldinfo = new fileInfo(oldFile);
    newinfo = new fileInfo(newFile);
    /* we don't process until we know both files really do exist. */
    try {
      inputscanoldinfo );
      inputscannewinfo );
    catch (IOException e) {
      System.err.println("Read error: " + e);
    }

    /* Now that we've read all the lines, allocate some arrays.
     */
    blocklen = new int[ (oldinfo.maxLine>newinfo.maxLine?
      oldinfo.maxLine : newinfo.maxLine];
    oldinfo.alloc();
    newinfo.alloc();

    /* Now do the work, and print the results. */
    transform();
    printout();
  }

  /**
   * inputscan    Reads the file specified by pinfo.file.
   * ---------    Places the lines of that file in the symbol table.
   *              Sets pinfo.maxLine to the number of lines found.
   */
  void inputscanfileInfo pinfo throws IOException
  {
       String linebuffer;

       pinfo.maxLine = 0;
       while ((linebuffer = pinfo.file.readLine()) != null) {
           storelinelinebuffer, pinfo );
       }
  }

  /**
   * storeline    Places line into symbol table.
   * ---------    Expects pinfo.maxLine initted: increments.
   *              Places symbol table handle in pinfo.ymbol.
   *              Expects pinfo is either oldinfo or newinfo.
   */
  void storelineString linebuffer, fileInfo pinfo )
  {
       int linenum = ++pinfo.maxLine;    /* note, no line zero */
       if linenum > fileInfo.MAXLINECOUNT ) {
      System.err.println"MAXLINECOUNT exceeded, must stop." );
      System.exit(1);
       }
       pinfo.symbollinenum =
      node.addSymbollinebuffer, pinfo == oldinfo, linenum );
  }

  /*
   * transform    
   * Analyzes the file differences and leaves its findings in
   * the global arrays oldinfo.other, newinfo.other, and blocklen.
   * Expects both files in symtab.
   * Expects valid "maxLine" and "symbol" in oldinfo and newinfo.
   */
  void transform()
  {                                  
       int oldline, newline;
       int oldmax = oldinfo.maxLine + 2;  /* Count pseudolines at  */
       int newmax = newinfo.maxLine + 2;  /* ..front and rear of file */

       for (oldline=0; oldline < oldmax; oldline++ )
      oldinfo.other[oldline]= -1;
       for (newline=0; newline < newmax; newline++ )
      newinfo.other[newline]= -1;

       scanunique();  /* scan for lines used once in both files */
       scanafter();   /* scan past sure-matches for non-unique blocks */
       scanbefore();  /* scan backwards from sure-matches */
       scanblocks();  /* find the fronts and lengths of blocks */
  }

  /*
   * scanunique
   * Scans for lines which are used exactly once in each file.
   * Expects both files in symtab, and oldinfo and newinfo valid.
   * The appropriate "other" array entries are set to the line# in
   * the other file.
   * Claims pseudo-lines at 0 and XXXinfo.maxLine+1 are unique.
   */
  void scanunique()
  {
       int oldline, newline;
       node psymbol;

       fornewline = 1; newline <= newinfo.maxLine; newline++ ) {
      psymbol = newinfo.symbolnewline ];
      if psymbol.symbolIsUnique()) {        // 1 use in each file
           oldline = psymbol.linenum;
           newinfo.othernewline = oldline; // record 1-1 map
           oldinfo.otheroldline = newline;
      }
       }
       newinfo.other0;
       oldinfo.other0;
       newinfo.othernewinfo.maxLine + = oldinfo.maxLine + 1;
       oldinfo.otheroldinfo.maxLine + = newinfo.maxLine + 1;
  }

  /*
   * scanafter
   * Expects both files in symtab, and oldinfo and newinfo valid.
   * Expects the "other" arrays contain positive #s to indicate
   * lines that are unique in both files.
   * For each such pair of places, scans past in each file.
   * Contiguous groups of lines that match non-uniquely are
   * taken to be good-enough matches, and so marked in "other".
   * Assumes each other[0] is 0.
   */
  void scanafter()
  {
       int oldline, newline;

       fornewline = 0; newline <= newinfo.maxLine; newline++ ) {
      oldline = newinfo.othernewline ];
      if oldline >= ) {  /* is unique in old & new */
           for(;;) {  /* scan after there in both files */
          if ++oldline > oldinfo.maxLine   break
          if oldinfo.otheroldline >= break;
          if ++newline > newinfo.maxLine   break
          if newinfo.othernewline >= break;

          /* oldline & newline exist, and 
        aren't already matched */

          if newinfo.symbolnewline !=
        oldinfo.symbololdline ] ) break;  // not same

          newinfo.other[newline= oldline; // record a match
          oldinfo.other[oldline= newline;
           }
      }
       }
  }

  /**
   * scanbefore
   * As scanafter, except scans towards file fronts.
   * Assumes the off-end lines have been marked as a match.
   */
  void scanbefore()
  {
       int oldline, newline;

       fornewline = newinfo.maxLine + 1; newline > 0; newline-- ) {
      oldline = newinfo.othernewline ];
      if oldline >= ) {               /* unique in each */
           for(;;) {
          if --oldline <= 0                break;
          if oldinfo.otheroldline >= break;
          if --newline <= 0                break;
          if newinfo.othernewline >= break;
     
          /* oldline and newline exist,
        and aren't marked yet */

          if newinfo.symbolnewline !=
        oldinfo.symbololdline ] ) break;  // not same

          newinfo.other[newline= oldline; // record a match
          oldinfo.other[oldline= newline;
           }
      }
       }
  }

  /**
   * scanblocks - Finds the beginnings and lengths of blocks of matches.
   * Sets the blocklen array (see definition).
   * Expects oldinfo valid.
   */
  void scanblocks()
  {
       int oldline, newline;
       int oldfront = 0;      // line# of front of a block in old, or 0 
       int newlast = -1;      // newline's value during prev. iteration

       foroldline = 1; oldline <= oldinfo.maxLine; oldline++ )
           blocklenoldline 0;
       blocklenoldinfo.maxLine + = UNREAL; // starts a mythical blk

       foroldline = 1; oldline <= oldinfo.maxLine; oldline++ ) {
      newline = oldinfo.otheroldline ];
      if newline < oldfront = 0;  /* no match: not in block */
      else{                                   /* match. */
           if oldfront == )         oldfront = oldline;
           if newline != (newlast+1)) oldfront = oldline;
           ++blocklenoldfront ];            
      }
      newlast = newline;
       }
  }

  /* The following are global to printout's subsidiary routines */
  // enum{ idle, delete, insert, movenew, moveold,
  // same, change } printstatus;
  public static final int
    idle = 0delete 1insert 2, movenew = 3, moveold = 4,
    same = 5, change = 6;
  int printstatus;
  boolean anyprinted;
  int printoldline, printnewline;     // line numbers in old & new file

  /**
   * printout - Prints summary to stdout.
   * Expects all data structures have been filled out.
   */
  void printout()
  {
       printstatus = idle;
       anyprinted = false;
       forprintoldline = printnewline = 1; ; ) {
      if printoldline > oldinfo.maxLine ) { newconsume()break;}
      if printnewline > newinfo.maxLine ) { oldconsume()break;}
      if (      newinfo.otherprintnewline ) {
           if oldinfo.otherprintoldline )
        showchange();
           else
        showinsert();
      }
      else if oldinfo.otherprintoldline )
      showdelete();
      else if blocklenprintoldline )
      skipold();
      else if oldinfo.otherprintoldline == printnewline )
      showsame();
      else
      showmove();
       }
       if anyprinted == true println">>>> End of differences."  );
       else                     println">>>> Files are identical." );
  }

  /*
   * newconsume        Part of printout. Have run out of old file. 
   * Print the rest of the new file, as inserts and/or moves.
   */
  void newconsume()
  {
       for(;;) {
      if printnewline > newinfo.maxLine )
      break;        /* end of file */
      if newinfo.otherprintnewline showinsert();
      else                                    showmove();
       }
  }

  /**
   * oldconsume        Part of printout. Have run out of new file.
   * Process the rest of the old file, printing any
   * parts which were deletes or moves.
   */
  void oldconsume()
  {
       for(;;) {
      if printoldline > oldinfo.maxLine )
      break;       /* end of file */
      printnewline = oldinfo.otherprintoldline ];
      if printnewline < showdelete();
      else if blocklenprintoldline skipold();
      else showmove();
       }
  }

  /**
   * showdelete        Part of printout.
   * Expects printoldline is at a deletion.
   */
  void showdelete()
  {
    if printstatus != delete )
      println">>>> DELETE AT " + printoldline);
    printstatus = delete;
    oldinfo.symbolprintoldline ].showSymbol();
    anyprinted = true;
    printoldline++;
  }

  /*
   * showinsert        Part of printout.
   * Expects printnewline is at an insertion.
   */
  void showinsert()
  {
       if printstatus == change println">>>>     CHANGED TO" );
       else if printstatus != insert 
      println">>>> INSERT BEFORE " + printoldline );
       printstatus = insert;
       newinfo.symbolprintnewline ].showSymbol();
       anyprinted = true;
       printnewline++;
  }

  /**
   * showchange        Part of printout.
   * Expects printnewline is an insertion.
   *  Expects printoldline is a deletion.
   */
  void showchange()
  {
       if printstatus != change 
      println">>>> " + printoldline + " CHANGED FROM");
       printstatus = change;
       oldinfo.symbolprintoldline ].showSymbol();
       anyprinted = true;
       printoldline++;
  }

  /**
   * skipold           Part of printout.
   * Expects printoldline at start of an old block that has 
   * already been announced as a move.
   * Skips over the old block.
   */
  void skipold()
  {
       printstatus = idle;
       for(;;) {
      if ++printoldline > oldinfo.maxLine )
      break;     /* end of file  */
      if oldinfo.otherprintoldline )
      break;    /* end of block */
      if blocklenprintoldline ]!=0)
      break;          /* start of another */
       }
  }

  /**
   * skipnew           Part of printout.
   * Expects printnewline is at start of a new block that has
   * already been announced as a move.
   * Skips over the new block.
   */
  void skipnew()
  {
       int oldline;
       printstatus = idle;
       for(;;) {
      if ++printnewline > newinfo.maxLine )
      break;    /* end of file  */
      oldline = newinfo.otherprintnewline ];
      if oldline < )
      break;                         /* end of block */
      if blocklenoldline != 0)
      break;              /* start of another */
       }
  }

  /**
   * showsame          Part of printout.
   * Expects printnewline and printoldline at start of
   * two blocks that aren't to be displayed.
   */
  void showsame()
  {
       int count;
       printstatus = idle;
       if newinfo.otherprintnewline != printoldline ) {
      System.err.println("BUG IN LINE REFERENCING");
      System.exit(1);
       }
       count = blocklenprintoldline ];
       printoldline += count;
       printnewline += count;
  }

  /**
   * showmove          Part of printout.
   * Expects printoldline, printnewline at start of
   * two different blocks ( a move was done).
   */
  void showmove()
  {
       int oldblock = blocklenprintoldline ];
       int newother = newinfo.otherprintnewline ];
       int newblock = blocklennewother ];

       if newblock < skipnew();         // already printed.
       else if oldblock >= newblock ) {     // assume new's blk moved.
      blocklen[newother= -1;         // stamp block as "printed".
      println">>>> " + newother + 
      " THRU " (newother + newblock - 1
      " MOVED TO BEFORE " + printoldline );
      for; newblock > 0; newblock--, printnewline++ )
           newinfo.symbolprintnewline ].showSymbol();
      anyprinted = true;
      printstatus = idle;

       else                /* assume old's block moved */
      skipold();      /* target line# not known, display later */
  }

  /** Convenience wrapper for println */
  public void println(String s) {
    System.out.println(s);
  }
};        // end of main class!

/**
 * Class "node". The symbol table routines in this class all
 * understand the symbol table format, which is a binary tree.
 * The methods are: addSymbol, symbolIsUnique, showSymbol.
 */ 
class node{                       /* the tree is made up of these nodes */
  node pleft, pright;
  int linenum;

  static final int freshnode = 0,
  oldonce = 1, newonce = 2, bothonce = 3, other = 4;

  int /* enum linestates */ linestate;
  String line;

  static node panchor = null;    /* symtab is a tree hung from this */

  /**
   * Construct a new symbol table node and fill in its fields.
   @param        string  A line of the text file
   */
  nodeString pline)
  {
       pleft = pright = null;
       linestate = freshnode;
       /* linenum field is not always valid */     
       line = pline;
  }

  /**
   * matchsymbol       Searches tree for a match to the line.
   @param  String  pline, a line of text
   * If node's linestate == freshnode, then created the node.
   */
  static node matchsymbolString pline )
  {
       int comparison;
       node pnode = panchor;
       if panchor == null return panchor = new nodepline);
       for(;;) {
      comparison = pnode.line.compareTo(pline);
      if comparison == return pnode;          /* found */

      if comparison < ) {
           if pnode.pleft == null ) {
          pnode.pleft = new nodepline);
          return pnode.pleft;
           }
           pnode = pnode.pleft;
      }
      if comparison > ) {
           if pnode.pright == null ) {
          pnode.pright = new nodepline);
          return pnode.pright;
           }
           pnode = pnode.pright;
      }
       }
       /* NOTE: There are return stmts, so control does not get here. */
  }

  /**
   * addSymbol(String pline) - Saves line into the symbol table.
   * Returns a handle to the symtab entry for that unique line.
   * If inoldfile nonzero, then linenum is remembered.
   */
  static node addSymbolString pline, boolean inoldfile, int linenum )
  {
    node pnode;
    pnode = matchsymbolpline );  /* find the node in the tree */
    if pnode.linestate == freshnode ) {
      pnode.linestate = inoldfile ? oldonce : newonce;
    else {
      if (( pnode.linestate == oldonce && !inoldfile ||
          pnode.linestate == newonce &&  inoldfile )) 
           pnode.linestate = bothonce;
      else pnode.linestate = other;
    }
    if (inoldfilepnode.linenum = linenum;
    return pnode;
  }

  /**
   * symbolIsUnique    Arg is a ptr previously returned by addSymbol.
   * --------------    Returns true if the line was added to the
   *                   symbol table exactly once with inoldfile true,
   *                   and exactly once with inoldfile false.
   */
  boolean symbolIsUnique()
  {
    return (linestate == bothonce );
  }

  /**
   * showSymbol        Prints the line to stdout.
   */
  void showSymbol()
  {
    System.out.println(line);
  }
}


           
       
Related examples in the same category
1. 触摸:设置文件上次修改的时间
2. 用NIO在Java中复制文件
3. Java中的文件复制
4. 文件字数统计,输出排序结果
5. 使用渠道和缓冲器复制文件
6. 使用Java的IO的API文件复制使用Java的IO的API文件复制
7. 模仿的Unix grep按命令
8. Grep tools
9. BGrep: a regular expression search utility, like Unix grep
10. 文件串连
11. 使用Java API压缩文件
12. 使用Java IO API删除文件
13. Undent -删除前导空间
14. TeePrintStream tees all PrintStream operations into a file, rather like the UNIX tee(1) command
15. Java删除文件错误处理
16. DirTree -目录列表,UNIX或DOS或VMSDirTree -目录列表,UNIX或DOS或VMS
17. 清空目录
18. Report on a file's status in Java
19. 简单的目录列表
20. 只读文件
21. 根目录清单根目录清单
22. Java中的重命名文件
23. FNFilter - directory lister using FilenameFilter
24. mkdir examples
25. 删除名称相匹配的目录
26. 使用FilenameFilter列出修改的目录使用FilenameFilter列出修改的目录
27. Dir Stack Dir Stack
28. 字数统计
29. 计数文件中的字符
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.