[WorldWind学习]8.Cache对象

MainApplication的构造函数599行实例化了worldWindow的Cache属性。

// set Upper and Lower limits for Cache size control, in bytes
                long CacheUpperLimit = (long)Settings.CacheSizeMegaBytes * 1024L * 1024L;
                long CacheLowerLimit = (long)Settings.CacheSizeMegaBytes * 768L * 1024L;    //75% of upper limit
                //Set up the cache
                worldWindow.Cache = new Cache(
                    Settings.CachePath,
                    CacheLowerLimit,
                    CacheUpperLimit,
                    Settings.CacheCleanupInterval, 
                    Settings.TotalRunTime );

这之前先看一下432行Settings的定义,

public static WorldWindSettings Settings = new WorldWindSettings();

在487~501行Main函数中可以看到通过LoadSettings()函数实现settings的赋值。

// ParseArgs may set values that are used elsewhere,
// such as startFullScreen and CurrentSettingsDirectory.
ParseArgs(args);
if(CurrentSettingsDirectory == null)
{
      // load program settings from default directory
      LoadSettings();    
      World.LoadSettings();
}
else
{
    LoadSettings(CurrentSettingsDirectory);
    World.LoadSettings(CurrentSettingsDirectory);
}
View Code
 1 /// <summary>
 2         /// Deserializes and optionally decrypts settings
 3         /// </summary>
 4         private static void LoadSettings()
 5         {
 6             try
 7             {
 8                 Settings = (WorldWindSettings) SettingsBase.Load(Settings, SettingsBase.LocationType.User);
 9 
10                 if(!File.Exists(Settings.FileName))
11                 {
12                     Settings.PluginsLoadedOnStartup.Add("ShapeFileInfoTool");
13                     //Settings.PluginsLoadedOnStartup.Add("OverviewFormLoader");
14                     //Settings.PluginsLoadedOnStartup.Add("Atmosphere");
15                     Settings.PluginsLoadedOnStartup.Add("SkyGradient");
16                     Settings.PluginsLoadedOnStartup.Add("BmngLoader");
17                     //Settings.PluginsLoadedOnStartup.Add("Compass");
18                     //Settings.PluginsLoadedOnStartup.Add("ExternalLayerManagerLoader");
19                     Settings.PluginsLoadedOnStartup.Add("MeasureTool");
20                     //Settings.PluginsLoadedOnStartup.Add("MovieRecorder");
21                     Settings.PluginsLoadedOnStartup.Add("NRLWeatherLoader");
22                     Settings.PluginsLoadedOnStartup.Add("ShapeFileLoader");
23                     Settings.PluginsLoadedOnStartup.Add("Stars3D");
24                     Settings.PluginsLoadedOnStartup.Add("GlobalClouds");
25                     Settings.PluginsLoadedOnStartup.Add("PlaceFinderLoader");
26                     Settings.PluginsLoadedOnStartup.Add("LightController");
27 
28                     Settings.PluginsLoadedOnStartup.Add("Earthquake_2.0.2.1");
29                     Settings.PluginsLoadedOnStartup.Add("Historical_Earthquake_2.0.2.2");
30                     Settings.PluginsLoadedOnStartup.Add("KMLImporter");
31                     //Settings.PluginsLoadedOnStartup.Add("doublezoom");
32                     //Settings.PluginsLoadedOnStartup.Add("PlanetaryRings");
33                     Settings.PluginsLoadedOnStartup.Add("TimeController");
34                     //Settings.PluginsLoadedOnStartup.Add("WavingFlags");
35                     Settings.PluginsLoadedOnStartup.Add("ScaleBarLegend");
36                     Settings.PluginsLoadedOnStartup.Add("Compass3D");
37                     Settings.PluginsLoadedOnStartup.Add("AnaglyphStereo");
38                     Settings.PluginsLoadedOnStartup.Add("GlobeIcon");
39 
40                 }
41                 // decrypt encoded user credentials
42                 DataProtector dp = new DataProtector(DataProtector.Store.USE_USER_STORE);
43 
44                 if(Settings.ProxyUsername.Length > 0) Settings.ProxyUsername = dp.TransparentDecrypt(Settings.ProxyUsername);
45                 if(Settings.ProxyPassword.Length > 0) Settings.ProxyPassword = dp.TransparentDecrypt(Settings.ProxyPassword);
46             }
47             catch(Exception caught)
48             {
49                 Log.Write(caught);
50             }
51         }

Settings = (WorldWindSettings) SettingsBase.Load(Settings, SettingsBase.LocationType.User);这句代码需要详细查看, SettingsBase.LocationType.User

View Code
 1 public static string DefaultLocation(LocationType locationType)
 2         {
 3             string directory;
 4 
 5             switch(locationType) 
 6             {
 7                 case LocationType.UserLocal:
 8                     // Example: @"C:\Documents and Settings\<user>\Local Settings\Application Data\NASA\NASA World Wind\1.3.3.11250"
 9                     return Application.LocalUserAppDataPath;
10                 
11                 case LocationType.UserCommon:
12                     // Example: @"C:\Documents and Settings\All Users\Application Data\NASA\NASA World Wind\1.3.3.11250"
13                     return Application.CommonAppDataPath;
14                 
15                 case LocationType.Application:
16                     // Example: @"C:\Program Files\NASA\World Wind\"
17                     return Application.StartupPath;
18 
19                 default:
20                     // fall through to regular (roaming) user
21                 case LocationType.User:   
22                     // Example: @"C:\Documents and Settings\<user>\Application Data\NASA\World Wind\1.3.3"
23                     directory = Log.DefaultSettingsDirectory();
24                     Directory.CreateDirectory(directory);
25                     return directory;
26             }
27         }

设置断点会发现directory的路径为:‘C:\Users\yangfan\AppData\Roaming\NASA\World Wind\1.4.0.0’,进入一看,原来是日志文件和World、WorldWind配置文件。

我还以为是影像或者矢量数据的缓存呢!

SettingsBase利用XmlSerializer实现配置文件保存。

MainApplication中只有开始介绍的一句实例化了worldWindow的Cache属性,而WorldWindow类中也只有private Cache m_Cache;属性定义。

注意到Cache类中定义了对象:Timer m_timer;

 1 /// <summary>
 2         /// Initializes a new instance of the <see cref= "T:WorldWind.Cache"/> class.
 3         /// </summary>
 4         /// <param name="cacheDirectory">Location of the cache files.</param>
 5         /// <param name="cleanupFrequencyInterval">Frequency of cache cleanup.</param>
 6         /// <param name="totalRunTime">Total duration application has been running so far.</param>
 7         public Cache(
 8             string cacheDirectory,
 9             TimeSpan cleanupFrequencyInterval,
10             TimeSpan totalRunTime)
11         {
12             this.CleanupFrequency = cleanupFrequencyInterval;
13             this.CacheDirectory = cacheDirectory;
14             Directory.CreateDirectory(this.CacheDirectory);
15 
16             // Start the timer
17             double firstDueSeconds = cleanupFrequencyInterval.TotalSeconds - 
18                 totalRunTime.TotalSeconds % cleanupFrequencyInterval.TotalSeconds;
19             m_timer = new Timer( new TimerCallback(OnTimer), null,
20                 (long)(firstDueSeconds*1000),
21                 (long)cleanupFrequencyInterval.TotalMilliseconds );
22         }
23 
24         /// <summary>
25         /// Constructor.
26         /// </summary>
27         /// <param name="cacheDirectory">Location of the cache files.</param>
28         /// <param name="cleanupFrequencyInterval">Frequency of cache cleanup.</param>
29         /// <param name="totalRunTime">Total duration application has been running so far.</param>
30         public Cache(
31             string cacheDirectory,
32             long cacheLowerLimit,
33             long cacheUpperLimit,
34             TimeSpan cleanupFrequencyInterval,
35             TimeSpan totalRunTime)
36             : this(cacheDirectory, cleanupFrequencyInterval, totalRunTime )
37         {
38             this.CacheLowerLimit = cacheLowerLimit;
39             this.CacheUpperLimit = cacheUpperLimit;
40         }

延迟后,每间隔cleanupFrequencyInterval.TotalMilliseconds调用OnTimer方法执行清理。

 1 /// <summary>
 2         /// Monitors the cache, makes sure it stays within limits.
 3         /// </summary>
 4         private void OnTimer(object state)
 5         {
 6             try
 7             {
 8                 // We are are not in a hurry
 9                 Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
10 
11                 // dirSize is reported as the total of the file sizes, in bytes
12                 // TODO: use the on-disk filesize, not FileInfo.Length, to calculate dirSize
13                 long dirSize = GetDirectorySize(new DirectoryInfo(this.CacheDirectory));//dirSize是缓存文件夹的大小
14                 if(dirSize < this.CacheUpperLimit)//小于限定值不清理
15                     return;
16 
17                 ArrayList fileInfoList = GetDirectoryFileInfoList(new DirectoryInfo(this.CacheDirectory));
18                 while(dirSize > this.CacheLowerLimit)
19                 {
20                     if (fileInfoList.Count <= 100)
21                         break;
22 
23                     FileInfo oldestFile = null;
24                     foreach(FileInfo curFile in fileInfoList)
25                     {
26                         if(oldestFile == null)
27                         {
28                             oldestFile = curFile;
29                             continue;
30                         }
31 
32                         if(curFile.LastAccessTimeUtc < oldestFile.LastAccessTimeUtc)
33                         {
34                             oldestFile = curFile;
35                         }
36                     }
37 
38                     fileInfoList.Remove(oldestFile);
39                     dirSize -= oldestFile.Length;
40                     try
41                     {
42                         File.Delete(oldestFile.FullName);
43 
44                         // Recursively remove empty directories
45                         string directory = oldestFile.Directory.FullName;
46                         while(Directory.GetFileSystemEntries(directory).Length==0)
47                         {
48                             Directory.Delete(directory);
49                             directory = Path.GetDirectoryName(directory);
50                         }
51                     }
52                     catch(IOException)
53                     {
54                         // Ignore non-removable file - move on to next
55                     }
56                 }
57             }
58             catch(Exception caught)
59             {
60                 Log.Write(Log.Levels.Error, "CACH", caught.Message);
61             }
62         }

计算缓存文件夹大小:

View Code
 1 public static long GetDirectorySize(DirectoryInfo inDir)
 2         {
 3             long returnBytes = 0;
 4             foreach(DirectoryInfo subDir in inDir.GetDirectories())
 5             {
 6                 returnBytes += GetDirectorySize(subDir);
 7             }
 8             foreach(FileInfo fi in inDir.GetFiles())
 9             {
10                 try
11                 {
12                     returnBytes += fi.Length;
13                 } 
14                 catch(System.IO.IOException)
15                 {
16                     // Ignore files that may have disappeared since we started scanning.
17                 }
18             }
19             return returnBytes;
20         }

 

转载于:https://www.cnblogs.com/yhlx125/archive/2013/04/20/2987107.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值