[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配置文件。

[WorldWind学习]8.Cache对象

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

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         }

 

你可能感兴趣的:(cache)