⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileexpirationservice.java

📁 jxme的一些相关程序,主要是手机上程序开发以及手机和计算机通信的一些程序资料,程序编译需要Ant支持
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

                        log (SCHEDULE, file, timeInMyCache, timeoutForOthers);

                        mods++;
                    }
                    return;
                }

                // There is such a file already. It gets tricky.

                // If we already have it with a longer life time, do not change
                // anything at all.
                if (entry.timeInMyCache > timeInMyCache) return;

                // If nothing is changed at all do not bother messing with it.
                if (entry.timeInMyCache == timeInMyCache &&
                    entry.timeoutForOthers == timeoutForOthers) return;
            
                // For now do not put restrictions on expiration time.

                hash.remove (file.getAbsolutePath ());

                // We have to cancel and that cannot be done under synch. So
                // drop the lock and cancel. Then try again the whole deal.
                // Do that until we get the right of way.
            }
            // NB: cancelling an action that has already been carried out
            // and removed from the scheduler does not hurt.
            ss.cancelAction (entry.myPendingAction);
        }
    }
    
    // There's no garantee that a new expiration does not get scheduled
    // right after we cancel, though.
    public void cancelFileExpiration (File file) {

        Entry e = null;
        synchronized (this) {
            e = (Entry) hash.get (file.getAbsolutePath ());
	
            if (e == null) return;

            hash.remove (file.getAbsolutePath ());
	    
	    log (CANCEL, file, 0, 0);

	    mods++;
	}
        // NB: cancelling an action that has already been carried out
        // and removed from the scheduler does not hurt.
        ss.cancelAction (e.myPendingAction);
    }
 
    void log (int action, File file, long timeInMyCache, long timeoutForOthers)
    {
	try {

	    logWrite (action, file, timeInMyCache, timeoutForOthers);

	} catch (IOException e) {

	    try {

		compress ();

		logWrite (action, file, timeInMyCache, timeoutForOthers);

	    } catch (IOException e2) {
		// what can we do but log it?
		// while the code is running, we'll keep
		// the expiration tables in memory.
		if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Cannot write to " + db + ", keeping expiration tables in memory.");
	    }
	}
    }

    void logWrite (int action, 
		   File file, 
		   long timeInMyCache, 
		   long timeForOthers) 
	throws IOException
    {
	out.writeInt  (action);
	out.writeUTF  (file.getAbsolutePath ().toString ());
	out.writeLong (timeInMyCache);
	out.writeLong (timeForOthers);

	out.getFD ().sync ();
    }

    // This is never executed in parallel, so it does not need to synch
    // what only compress touches (db, tmpDb).
    private void compress () throws IOException {
	
	DataInputStream  in  = null;
	long start = System.currentTimeMillis ();
	
	// if the output stream is open, close it
	if (out != null) {

	    try {
		out.close ();
	    } catch (IOException e) {

	    }
	}

	if (tmpDb.exists ())
		tmpDb.delete ();

	// open an input stream to read existing log
	// open an output stream to a temporary file
	// compress input stream into output stream

	try {
	    in  = new DataInputStream(new BufferedInputStream(new FileInputStream (db)));
	    out = new RandomAccessFile (tmpDb, "rw");
	    
	    compressStreams (in);

	} finally {

	    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Compressed " + db + " in " + (System.currentTimeMillis () - start) + " ms.");
	    // make sure we close all streams
	    if (in != null) 
		try {
		    in.close ();
		} catch (IOException e) {

		}
	    
	    if (out != null)
		try {
		    out.close ();
		} catch (IOException e) {

		}
	    
		if (tmpDb.exists ()) {
			if (db.exists ()) // an existing file will prevent rename on win2k!
				db.delete (); 
			tmpDb.renameTo (db); // if we deleted but rename failed, oh well
		}

	    out = new RandomAccessFile (db, "rw");
	    out.seek (out.length ());
	}
	
	removeUnknownFiles ();

	mods = 0;
    }
    

    void compressStreams (DataInputStream in) throws IOException {
	int  action;
	File file;
	long timeInMyCache;
	long timeoutForOthers;
	int i = 0;
	
	try {
	    while (true) {
		
		action           = in.readInt ();
		file             = new File (in.readUTF ());
		timeInMyCache    = in.readLong ();
		timeoutForOthers = in.readLong ();
		
		
		if (file.exists ()) {
		    		    
		    switch (action) {
			
		    case SCHEDULE:
			
			if (timeInMyCache > System.currentTimeMillis ())
			    scheduleFileExpiration (file, 
						    timeInMyCache, 
						    timeoutForOthers);
			break;
			
		    case CANCEL:
			
			cancelFileExpiration (file);
			break;
		    }
		}

		i++;
		
	    }
	} catch (EOFException e) {
	    // ugh, this is bad code, but should work all the time
	}
    }


    void removeUnknownFiles () {
	Enumeration e = docDirs.elements ();

	while (e.hasMoreElements ()) {
	    File dir = (File) e.nextElement ();

	    removeUnknownFiles (dir);
	}
    }
    
    void removeUnknownFiles (File dir) {
	File f;
	String[] list = dir.list ();
	
	
	for (int i = 0;  list != null && i < list.length;  i++) {
	    
	    f = new File (dir, list[i]);
	    if (! f.isDirectory () && 
		hash.get (f.getAbsolutePath ()) == null && // we don't know anything
		f.getName ().indexOf ("scheduler.db") == -1) {  // not our db file
		try {
			if (listener != null) listener.expiredAndRemove (f);
		} catch (Throwable t) {
			if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Throwable caught while dispatching expiration listener.", t);
		} finally {
                    f.delete();
                }
            }
	}
    }

	

    public static void main (String[] argv) throws IOException {
	SchedulerService ss = new SchedulerService ();
	FileExpirationService fes;
	File dir = new File (argv[0]);
	Thread t = new Thread (ss);

	t.start ();

	fes = new FileExpirationService (ss, dir, null, null);
	
	fes.addDocDir (new File ("testdir/"));

	long time = System.currentTimeMillis () + 30 * 1000;
	
	fes.scheduleFileExpiration (new File ("testdir/test1"), time, time);
	fes.scheduleFileExpiration (new File ("testdir/test2"), time, time);
	fes.scheduleFileExpiration (new File ("testdir/test3"), time, time);

	fes.cancelFileExpiration (new File ("testdir/test2"));
    }
}
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -