예제 #1
0
        } // end _PruneLogFiles()

        private static void _PruneFilesNotInUse(string dir, string pattern, long cbMaxSize)
        {
            const int MIN_LOG_BYTES = 1024 * 1024;

            if (cbMaxSize < MIN_LOG_BYTES)
            {
                Util.Fail("should not happen");   // safe to use Util.Fail here
                cbMaxSize = MIN_LOG_BYTES;
            }

            using (ExceptionGuard disposer = new ExceptionGuard())
            {
                DirectoryInfo     di        = new DirectoryInfo(dir);
                FileSystemInfo[]  fsis      = di.GetFileSystemInfos(pattern);
                List <FileInfo>   files     = new List <FileInfo>(fsis.Length);
                List <FileStream> fileLocks = new List <FileStream>(fsis.Length);
                disposer.ProtectAll(fileLocks);   // it does not make a copy of the list, so it's okay that we haven't put anything in yet.
                long totalSize = 0;
                foreach (FileSystemInfo fsi in fsis)
                {
                    FileInfo fi = fsi as FileInfo;
                    if (null != fi)
                    {
                        // We only count not-in-use files against our disk limit. If the
                        // file is not in use, this will "lock" it (making it appear
                        // in-use to anybody else) and put the resulting FileStream in the
                        // fileLocks list.
                        if (_FileNotInUse(fi, fileLocks))
                        {
#if DEBUG_LOG_PRUNING
                            Trace("File \"{0}\" is NOT in use. (it will be considered for pruning)", fi.FullName);
#endif
                            fi.Refresh(); // in case _FileNotInUse finalized it.
                            totalSize += fi.Length;
                            files.Add(fi);
                        }
#if DEBUG_LOG_PRUNING
                        else
                        {
                            Trace("File \"{0}\" is in use.", fi.FullName);
                        }
#endif
                    }
                }

                if (totalSize <= cbMaxSize)
                {
                    // Don't need to prune anything.
                    return;
                }

                // Sort by age: oldest first.
                files.Sort((x, y) => x.CreationTime.CompareTo(y.CreationTime));

                long cbDeletedSoFar = 0;
                long cbNeedToDelete = totalSize - cbMaxSize;
                int  idxCandidate   = 0;
                while ((idxCandidate < files.Count) &&
                       (cbDeletedSoFar < cbNeedToDelete))
                {
                    if (_TryDeleteOldFile(files[idxCandidate].FullName))
                    {
                        cbDeletedSoFar += files[idxCandidate].Length;
                    }
                    idxCandidate++;
                }

                if (cbDeletedSoFar < cbNeedToDelete)
                {
                    Trace("Warning: could not delete enough log files matching \"{0}\" from \"{1}\" to get under the limit of {2}.",
                          pattern,
                          dir,
                          Util.FormatByteSize(cbMaxSize));
                }
            } // end using( disposer ) <-- the files will actually get deleted here when we close the FileStream handles.
        }     // end _PruneFilesNotInUse()