/*******************************************************************************
*
* 只运行一个实例
*
* 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 );
}
}