Comparando conteudo de 2 arquivos

Nunca pensei que algo tao simples fosse dar tanta dor de cabeca.
ja procurei tantas outras alternativas mais nenhuma outra se da certo
eu to apanhando muito do java e o programa nao saii nemmm.

é o seguinte o programa precisa exibir diferencas entre 2 arquivos e salvalas em outro , o problema esta justamente na comparacao pq o resto
eu tenho uma base. mais aii vaii , por exemplo

[code]arquivo1.txt arquivo2.txt
1 1
2 5
3 6
4 7
5 8
6 9

    >>>  [JAVA COMPARA] <<<

intersecção1-2.txt
2
3
4

intersecção2-1.txt
7
8
9[/code]

e tao simples , mais ja queimei neuronio de mais , e nao saii nemm, rsss
os arquivos que tem que comparar sao exatamente tabelas de numeros
assim como coloquei no exemplo , alguma sugestao ?

poxaa kra , valeww de maiss
esse programa ai , faz basicamente a mesma
coisa do FC.exe do windows , mais sendo em
java eu acabo de ageitar ele do geito que eu preciso
Obrigado. :smiley:

Boa tarde!
Existem várias implementações desse programa conhecido como Diff! Se é apenas um exercício estou acabando com a graça! rs
Estou enviando uma versão retirada de http://www.darwinsys.com/freeware/Diff.java

O Diff recebe dois parâmetros: arquivo1.txt arquivo2.txt

[code]import java.io.*;

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. */


fileInfo( String filename ) {
	symbol = new node [ MAXLINECOUNT+2 ];
	other  = null;		// allocated later!
	try {
		file = new DataInputStream(
			new FileInputStream( filename));
	} 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];
}

};

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;


int blocklen[];


public static void main(String argstrings[])
{
	if ( argstrings.length != 2 ) {
	  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 {
		inputscan( oldinfo );
		inputscan( newinfo );
	} 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) + 2 ];
	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 inputscan( fileInfo pinfo ) throws IOException
{
     String linebuffer;

     pinfo.maxLine = 0;
     while ((linebuffer = pinfo.file.readLine()) != null) {
	       storeline( linebuffer, 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 storeline( String 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.symbol[ linenum ] =
	  node.addSymbol( linebuffer, 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 */
}


void scanunique()
{
     int oldline, newline;
     node psymbol;

     for( newline = 1; newline <= newinfo.maxLine; newline++ ) {
	  psymbol = newinfo.symbol[ newline ];
	  if ( psymbol.symbolIsUnique()) {        // 1 use in each file
	       oldline = psymbol.linenum;
	       newinfo.other[ newline ] = oldline; // record 1-1 map
	       oldinfo.other[ oldline ] = newline;
	  }
     }
     newinfo.other[ 0 ] = 0;
     oldinfo.other[ 0 ] = 0;
     newinfo.other[ newinfo.maxLine + 1 ] = oldinfo.maxLine + 1;
     oldinfo.other[ oldinfo.maxLine + 1 ] = newinfo.maxLine + 1;
}


void scanafter()
{
     int oldline, newline;

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

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

		    if ( newinfo.symbol[ newline ] !=
			oldinfo.symbol[ oldline ] ) 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;

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

		    if ( newinfo.symbol[ newline ] !=
			oldinfo.symbol[ oldline ] ) 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

     for( oldline = 1; oldline <= oldinfo.maxLine; oldline++ )
	       blocklen[ oldline ] = 0;
     blocklen[ oldinfo.maxLine + 1 ] = UNREAL; // starts a mythical blk

     for( oldline = 1; oldline <= oldinfo.maxLine; oldline++ ) {
	  newline = oldinfo.other[ oldline ];
	  if ( newline < 0 ) oldfront = 0;  /* no match: not in block */
	  else{                                   /* match. */
	       if ( oldfront == 0 )         oldfront = oldline;
	       if ( newline != (newlast+1)) oldfront = oldline;
	       ++blocklen[ oldfront ];            
	  }
	  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 = 0, delete = 1, insert = 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;
     for( printoldline = printnewline = 1; ; ) {
	  if ( printoldline > oldinfo.maxLine ) { newconsume(); break;}
	  if ( printnewline > newinfo.maxLine ) { oldconsume(); break;}
	  if (      newinfo.other[ printnewline ] < 0 ) {
	       if ( oldinfo.other[ printoldline ] < 0 )
			showchange();
	       else
			showinsert();
	  }
	  else if ( oldinfo.other[ printoldline ] < 0 )
		showdelete();
	  else if ( blocklen[ printoldline ] < 0 )
		skipold();
	  else if ( oldinfo.other[ printoldline ] == 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.other[ printnewline ] < 0 ) 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.other[ printoldline ];
	  if ( printnewline < 0 ) showdelete();
	  else if ( blocklen[ printoldline ] < 0 ) 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.symbol[ printoldline ].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.symbol[ printnewline ].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.symbol[ printoldline ].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.other[ printoldline ] < 0 )
		break;    /* end of block */
	  if ( blocklen[ printoldline ]!=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.other[ printnewline ];
	  if ( oldline < 0 )
		break;                         /* end of block */
	  if ( blocklen[ oldline ] != 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.other[ printnewline ] != printoldline ) {
	  System.err.println("BUG IN LINE REFERENCING");
	  System.exit(1);
     }
     count = blocklen[ printoldline ];
     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 = blocklen[ printoldline ];
     int newother = newinfo.other[ printnewline ];
     int newblock = blocklen[ newother ];

     if ( newblock < 0 ) 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.symbol[ printnewline ].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
      /
      node( String 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 matchsymbol( String pline )
      {
      int comparison;
      node pnode = panchor;
      if ( panchor == null ) return panchor = new node( pline);
      for(;:wink: {
      comparison = pnode.line.compareTo(pline);
      if ( comparison == 0 ) return pnode; /
      found */

      if ( comparison < 0 ) {
      if ( pnode.pleft == null ) {
      pnode.pleft = new node( pline);
      return pnode.pleft;
      }
      pnode = pnode.pleft;
      }
      if ( comparison > 0 ) {
      if ( pnode.pright == null ) {
      pnode.pright = new node( pline);
      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 addSymbol( String pline, boolean inoldfile, int linenum )
      {
      node pnode;
      pnode = matchsymbol( pline ); /
      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 (inoldfile) pnode.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);
      }
      }
      [/code]