2012-02-02 35 views
1

我有一個靜態類,其中我保留了我的應用程序中不同位置使用的大量相對路徑。它看起來像這樣:如何組織大量的文件/目錄路徑常量

static class FilePathConstants 
{ 
    public const string FirstDirectory = "First"; 
    public const string FirstSecondDirectory = "First/Second"; 
    public const string FirstSecondThirdFileA = "First/Second/Third/FileA"; 
    public const string FirstSecondFourthFileB = "First/Second/Fourth/FileB"; 
    ... nearly 100 of similar members 
} 

所有這些都是相對於某些父目錄,只有在程序運行期間我才知道的位置。我需要將它們放在一起,因爲它可以讓我輕鬆控制應用程序使用哪些文件並不時更改其位置。

但是,即使它們按字母順序組織,並且很容易找到某個路徑,但我需要根據某些設置更改其中的一些。假設有一個設置'bool SettingA',當我打開它時,我必須修改一些路徑來使用不同的目錄或不同的文件名。

問題是,現在我不能使用常量,我必須重寫我的代碼屬性或方法,以便我可以在運行時更改文件路徑。在這裏,我的代碼變得更大,嚴格的順序現在看起來很醜。有沒有一種方法可以將它們分組,以便它不會混淆使用此代碼的任何人?我不能將他們分解成單獨的課程,因爲很難記住在什麼課程中你可能保持的常數。現在我將它們按地區分組,但我有一種不好的感覺,認爲在一個班級中保留超過一百個房產是錯誤的。

編輯:

所有的目錄和文件,我在FilePathConstants聲明在大量的應用程序的地方使用(每個路徑可以多次使用,考慮到這一事實,有更多的則是一百條路徑 - 這是一個很大的數字)。我想保持這個類的接口相同,或者對其他使用它們的類進行最小的修改。

回答

1

,也許你可以使用rowstructs

+0

'rowstructs'是什麼意思? – username 2012-02-02 18:07:21

+0

這是一個半類,類,但在這種情況下更輕,更有用,在這種情況下類可能會「重」這個用法,建議使用rowstructs – 2012-02-03 14:48:30

1

使用類似「指數」的文件存放的目錄路徑,並在運行時加載它。

const string indexFilePath = @"C:\dirlist.txt"; 
IEnumerable<string> paths = File.ReadAllLines(indexFilePath); 

更新

我想用間接暗示 - 「映射器」 類。 以下是它應該的樣子。

public enum FileSystemElement 
{ 
    FirstDirectory, 
    FirstSecondDirectory, 
    FirstSecondThirdFileA, 
    FirstSecondFourthFileB 
} 

public class FileSystemMapper 
{ 
    private readonly string _rootDirectory; 
    private readonly Dictionary<FileSystemElement, string> _fileElements; 

    public FileSystemMapper(string rootDirectory, string fileName) 
    { 
     _rootDirectory = rootDirectory; 
     string[] lines = File.ReadAllLines(fileName); 
     _fileElements = lines.Select(ParsePair).ToDictionary(pair => pair.Key, pair => pair.Value); 
    } 

    public string GetPath(FileSystemElement element) 
    { 
     string relativePath; 
     if (!_fileElements.TryGetValue(element, out relativePath)) 
     { 
      throw new InvalidOperationException("Element not found"); 
     } 

     string resultPath = Path.Combine(_rootDirectory, relativePath); 
     return resultPath; 
    } 

    private static KeyValuePair<FileSystemElement, string> ParsePair(string line) 
    { 
     const string separator = "|"; 

     // File element alias | Path 
     if (string.IsNullOrEmpty(line)) 
      throw new ArgumentException("Null or empty line", "line");     

     string[] components = line.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries); 
     if (components.Length != 2) 
      throw new ArgumentException("Line has invalid format", "line"); 

     FileSystemElement element; 
     bool parseResult = FileSystemElement.TryParse(components[0], out element); 
     if (!parseResult) 
      throw new ArgumentException("Invalid element name", "line"); 

     string path = components[1]; // for clarity 
     return new KeyValuePair<FileSystemElement, string>(element, path); 
    } 

客戶例如:

 FileSystemMapper fileSystemMapper = new FileSystemMapper(@"C:\root", @"C:\dirs.txt"); 
     string firstDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstDirectory); 
     string secondDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstSecondDirectory); 
     string secondThirdFile = fileSystemMapper.GetPath(FileSystemElement.FirstSecondThirdFileA); 

索引文件格式:<Element name>|<Path><New Line>

例子:

FirstDirectory|First 
FirstSecondDirectory|First\Second 
FirstSecondThirdFileA|First\Second\Third\FileA 
FirstSecondFourthFileB|First\Second\Fourth\FileB 
+0

假設我使用索引文件。那麼對於每一行我都必須創建一個方法或屬性。看起來我回到了我所在的地方 – username 2012-02-02 18:11:53

+0

不,'paths'變量包含了所有的目錄,所以你可以通過目錄來枚舉。 – 2012-02-02 18:19:34

+0

這意味着每次我需要一條路徑時,我必須枚舉一百條路徑,並且我無法保證它包含我的路徑 – username 2012-02-02 18:20:52

0

你能不能用你的項目Properties.Settings?它存儲在.config文件中,因此可以在部署後進行編輯

或者只是不讓它們爲const,那麼您可以在運行時編輯它們,它們會在下次運行時恢復爲原始設置。

or dont make the calss static並在每次使用它時創建一個實例,然後在完成時更改需要的內容並丟棄實例。

+0

我不使用Properties.Settings。問題是我需要將它們從常量改爲屬性,但它使我的代碼非常大而且很醜陋,我需要以某種方式組織這些路徑 – username 2012-02-02 18:18:18