posts - 41,  comments - 40,  trackbacks - 0

如何只运行一个实例,网上有三种方法(单模式不算):

1、占用端口(有效,但是有端口被挪用的缺陷)

2、检查文件是否存在(有效,但突然停机可能有问题)

3、使用JNI(有效,但丧失可移植性)

我写的和第二个原理差不多,判断某个文件是否被占用,并且我把记录日志、保存日志、判断是否运行放在一起。

你可以转载本Blog,但是不能篡改作者名称。

import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;

import javax.swing.JFrame;


/*******************************************************************************
 *
 * 只运行一个实例
 *
 * Just single instance
 *
 *
 * Author: NeedJava
 *
 * Modified: 2007.08.29
 *
 *
 * 你可以使用此程序于任何地方,但请保留程序作者及注释的完整。如果你改进了程序,
 *
 * 请在原作者后添加姓名,如:Author: NeedJava/Jack/Mike,版本及修改时间同理。
 *
 ******************************************************************************/
public final class SingleInstance
{
  /*****************************************************************************
   *
   * 构造函数
   *
   ****************************************************************************/
  private SingleInstance()
  {
    this( "vab", ".vab", "vab" );
  }


  public SingleInstance( String filePrefixName, String fileSuffixName, String directoryName )
  {
    this.init( filePrefixName, fileSuffixName, directoryName );
  }


  /*****************************************************************************
   *
   * 原理:
   *
   * 用重定向将标准错误输出流定向到一个日志文件,占用它,使其不能被删除
   *
   * 以后的实例试图将存在的此日志文件改名并且另存为某个文件夹下
   *
   * 如果成功,说明没有程序占用它(不排除你在用它,缺陷?),正好保存日志
   *
   * 如果不成功,退出、renameTo命令有一箭双雕的作用
   *
   ****************************************************************************/
  private final void init( String filePrefixName, String fileSuffixName, String directoryName )
  {
    if( filePrefixName==null||fileSuffixName==null||directoryName==null )
      {
        exitWithWarning( "Error: Invalid file name.", 10 );
      }

    //We need check the fileSuffixName here? From the tail?

    String fileName=filePrefixName+fileSuffixName;

    try{ File error=new File( fileName );

         if( error.exists() )
           {
             File directory=new File( directoryName );

             String newFileName=directoryName+File.separator+convertMillisecond2DateTime( error.lastModified() )+fileSuffixName;

             //System.out.println( newFileName );

             if( directory.exists() )
               {
                 if( directory.isDirectory() )
                   {
                     //renameTo也是好东东,既可以改名,还可以移文件
                     if( !error.renameTo( new File( newFileName ) ) )
                       {
                         exitWithWarning( "Error: The instance already exists, I will exit.", 11 );
                       }
                   }
                 else{ exitWithWarning( "Error: The \'"+directoryName+"\' is not a valid directory.", 21 );
                     }
               }
             else{ if( directory.mkdirs() )
                     {
                       //renameTo也是好东东,既可以改名,还可以移文件
                       if( !error.renameTo( new File( newFileName ) ) )
                         {
                           exitWithWarning( "Error: The instance already exists, I will exit.", 11 );
                         }
                     }
                   else{ exitWithWarning( "Error: Failed to create the \'"+directoryName+"\' directory.", 22 );
                       }
                 }
           }

         //重定向标准错误输出流,所有功能全靠它。来,啵一个
         System.setErr( new PrintStream( new FileOutputStream( fileName ) ) );
       }
    catch( FileNotFoundException fnfe )
         {
           //fnfe.printStackTrace();

           exitWithWarning( fnfe.toString(), 23 );
         }
    catch( IOException ioe )
         {
           //ioe.printStackTrace();

           exitWithWarning( ioe.toString(), 29 );
         }
    catch( Exception e )
         {
           //e.printStackTrace();

           exitWithWarning( e.toString(), 99 );
         }
  }


  /*****************************************************************************
   *
   * You can change the milliseconds to the date and time string here
   *
   * I just return the original
   *
   * Don't get the same string :)
   *
   ****************************************************************************/
  private final String convertMillisecond2DateTime( long millisecond )
  {
    return ""+millisecond;
  }


  /*****************************************************************************
   *
   * Return the warning and the exit code, then exit the application
   *
   ****************************************************************************/
  private final void exitWithWarning( String warning, int code )
  {
    System.out.println( warning==null ? "" : warning );

    System.exit( code );
  }


  /*****************************************************************************
   *
   * 主函数入口
   *
   ****************************************************************************/
  public final static void main( String[] args )
  {
    SingleInstance si=new SingleInstance( "error", ".txt", "error" );

    final JFrame frame=new JFrame( "Just single instance. By NeedJava. 2007.08.29" );

    //I stay here, to make some friends happy.
    frame.addWindowListener( new WindowAdapter()
    {
      public void windowClosing( WindowEvent we )
      {
        frame.dispose();

        System.exit( 0 );
      }
    } );

    frame.setBounds( 200, 200, 700, 70 );

    frame.setVisible( true );
  }
}

posted on 2007-08-29 22:11 NeedJava 阅读(3181) 评论(8)  编辑  收藏 所属分类: Java

只有注册用户登录后才能发表评论。


网站导航: