Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

NFS File Access problem

807606Mar 2 2007
Hello,

I am having problems trying to "tail" an existing file.
When the file is being written into, I can tail it without any problem.
The problem rises when the file is already complete, and I try to open it.

I tried to make a small demo program but for some reason I am unable to get the demo program to give the same behaviour.

Below is the class in which it all goes wrong.
I basically opens the file usring RandomAccessfile.
when I try to retrieve the length of the file a bit further, my ascii file I am viewing already changed to .nfs01231353434 something.
But all gets displayed ok.
When I then close the text pane in which this tail class is logging, the file itself is deleted.

As this has something to do with NFS here is the setup :

The java jar file is located on a remote solaris disk, so is the ASCII file I am trying to view.
The local machine where I am running my application is Red Hat Linux 3.2.3-52.

Apologies if this information is kinda vague but as I am unable to supply a demo program, I dont know else how to explain my problem.

The class that does the "tailing"
package com.alcatel.tamtam.main;

import java.io.*;
import java.util.*;

public class Usr_LogFileTrailer extends Thread
  {
  /**
   * How frequently to check for file changes; defaults to 5 seconds
   */
  private long sampleInterval = 5000;

  /**
   * Number of lines in a row we output, otherwise problems with large files
   */
   private int lineBuffer = 250;

  /**
   * The log file to tail
   */
  private File logfile;

  /**
   * Defines whether the log file tailer should include the entire contents
   * of the exising log file or tail from the end of the file when the tailer starts
   */
  private boolean startAtBeginning = false;

  /**
   * Is the tailer currently tailing ?
   */
  private boolean tailing = false;

  /**
   * Is the thread suspended or not ?
   */
  private boolean threadSuspended = true;

  /**
   * File pointer where thread last logged a line
   */
  private long filePointer = 0;

  /**
   * Set of listeners
   */
  private Set listeners = new HashSet();

  /**
   * Creates a new log file tailer that tails an existing file and checks the file for
   * updates every 5000ms
   */
  public Usr_LogFileTrailer( File file )
    {
    this.logfile = file;
    }

  /**
   * Creates a new log file tailer
   *
   * @param file         The file to tail
   * @param sampleInterval    How often to check for updates to the log file (default = 5000ms)
   * @param startAtBeginning   Should the tailer simply tail or should it process the entire
   *               file and continue tailing (true) or simply start tailing from the
   *               end of the file
   */
  public Usr_LogFileTrailer( File file, long sampleInterval, boolean startAtBeginning )
    {
    this.logfile = file;
    this.sampleInterval = sampleInterval;
    setPriority(Thread.MIN_PRIORITY);
    }

  public void addLogFileTailerListener( Usr_LogFileTrailerListener l )
    {
    this.listeners.add( l );
    }

  public void removeLogFileTailerListener( Usr_LogFileTrailerListener l )
  {
    this.listeners.remove( l );
  }

  /*
   *
   *  Methods to trigger our event listeners
   *
   */
  protected void fireNewLogFileLine( String line )
    {
    for( Iterator i=this.listeners.iterator(); i.hasNext(); )
      {
      Usr_LogFileTrailerListener l = ( Usr_LogFileTrailerListener )i.next();
      l.newLogFileLine( line );
      }
    }

  public void stopTailing()
    {
    this.tailing = false;
    }

  public void restart()
    {
    filePointer = 0;
    }

  public synchronized void setSuspended(boolean threadSuspended)
    {
    this.threadSuspended = threadSuspended;
    if ( ! threadSuspended ) notify();
    }

  public void run()
    {
    try
      {
      while ( ! logfile.exists() )
        {
        synchronized(this)
          {
          while ( threadSuspended ) wait();
          }
        Thread.currentThread().sleep(1000);
        File parentDir = logfile.getParentFile();
        if ( parentDir.exists() && parentDir.isDirectory() )
          {
          File[] parentFiles = parentDir.listFiles();
          for ( File parentFile : parentFiles )
            {
            if ( parentFile.getName().equals(logfile.getName()) ||
                 parentFile.getName().startsWith(logfile.getName() + "_child") )
              {
              logfile = parentFile;
              break;
              }
            }
          }
        }
      }
    catch(InterruptedException iEx)
      {
      iEx.printStackTrace();
      }

    // Determine start point
    if( this.startAtBeginning )
      {
      filePointer = 0;
      }

    try
      {
      // Start tailing
      this.tailing = true;

      RandomAccessFile file = new RandomAccessFile( logfile, "r" );
      while( this.tailing )
        {
        synchronized(this)
          {
          while ( threadSuspended ) wait();
          }
        try
          {
          // Compare the length of the file to the file pointer
//          long fileLength = 0;
          //long fileLength = file.length();
          long fileLength = this.logfile.length();
          if( fileLength < filePointer )
            {
            // Log file must have been rotated or deleted;
            // reopen the file and reset the file pointer
            file = new RandomAccessFile( logfile, "r" );
            filePointer = 0;
            }

          if( fileLength > filePointer )
            {
            // There is data to read
            file.seek( filePointer );
            String line = file.readLine();
            int lineCount = 0;
//            this.fireBlockTextPane();
            while( line != null && lineCount < lineBuffer)
              {
              this.fireNewLogFileLine( line );
              line = file.readLine();
              lineCount++;
              }
            filePointer = file.getFilePointer();
            this.fireFlushLogging();
//            this.fireNewTextPaneUpdate();
            }

          // Sleep for the specified interval
          sleep( this.sampleInterval );
          }
        catch( Exception e )
          {
            e.printStackTrace();
          }
        }

      // Close the file that we are tailing
      file.close();
      }
    catch( Exception e )
      {
      e.printStackTrace();
      }
    }
  }
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 30 2007
Added on Mar 2 2007
0 comments
569 views