2012-11-17 74 views
2

在VS 2010中,我有一個大的字符串列表,列表中的每個項目也包含字符串列表(它不會再繼續)。好的是隻有補充會發生。沒有任何東西會從列表中刪除。將列表清單保存到文件的最有效方式是?

我不想使用數據庫。由於列表可能會變得很大,XML對我來說似乎很慢。我找不到任何常見的解決方案。任何想法?

編輯:好吧,我的一些代碼會讓它更清晰。

Class Word 
    Public theWord As String 
    Public SubWords As New List(Of SubWord) 
    Public Count As Integer = 1 
    Sub New(ByRef Word As String) 
     theWord = Word 
    End Sub 
    Public Sub AddSubWord(ByRef Word As String) 
     Dim SubWordCount As Integer = SubWords.Count - 1 
     Dim Found As Boolean 
     For i = 0 To SubWordCount 
      If SubWords(i).theWord = Word Then 
       SubWords(i).Count += 1 
       Found = True 
       Exit For 
      End If 
     Next 
     If Found = False Then 
      SubWords.Add(New SubWord(Word)) 
     End If 
    End Sub 
    Public Overrides Function ToString() As String 
     Return theWord 
    End Function 
End Class 

Class SubWord 
    Public theWord As String 
    Public Count As Integer = 1 
    Sub New(ByRef Word As String) 
     theWord = Word 
    End Sub 
    Public Overrides Function ToString() As String 
     Return theWord 
    End Function 
End Class 

也榜上有名我是:

Dim Words As New List(Of Word) 

目的是增加一個單詞列表。如果字是不是在列表中,如果不增加它的數量。同樣的子詞。之後,所有列表將根據其數量進行排序。會有很多單詞,並且每個單詞都有一個巨大的子詞列表。

+1

「高效」是沒有意義的,除非你縮小範圍進一步。另外,在序列化中有許多**重要的注意事項:速度,大小,向前兼容性。那麼後者呢? – Jon

+0

更新了問題。 – theGD

+0

還有一些你沒有使用的主要原因列表 .Contains?你多久需要一份清單才能記憶和多久。加載和保存需要多長時間是「高效」方面的相關問題 –

回答

1

XML似乎是最好的選擇,但如果您真的關心效率,並且您確信將來數據結構不會改變,您可以將數據存儲在分隔文本文件中。例如:

Private Sub SaveList(filePath As String, list As List(Of List(Of String))) 
    Const fieldDelimiter As String = "," 
    Const recordDelimiter As String = Environment.NewLine 
    Dim temp As New List(Of String)() 
    For each i as List(Of String) in list) 
     temp.Add(String.Join(fieldDelimiter, i.ToArray())) 
    Next 
    Dim contents As String = String.Join(recordDelimiter, temp.ToArray()) 
    File.WriteAllText(filePath, contents) 
End Sub 

或者,更有效地:

Private Sub SaveList(filePath As String, list As List(Of List(Of String))) 
    Const fieldDelimiter As String = "," 
    Const recordDelimiter As String = Environment.NewLine 
    Using writer As New StreamWriter(filePath) 
     Dim firstRecord As Boolean = True 
     For Each record as List(Of String) In list) 
      If firstRecord Then 
       firstRecord = False 
      Else 
       writer.Write(recordDelimiter) 
      End If 
      Dim firstField As Boolean = True 
      For Each field As String In record 
       If firstField Then 
        firstField = False 
       Else 
        writer.Write(fieldDelimiter) 
       End If 
       writer.Write(field) 
      Next 
     Next 
    End Using 
End Sub  

這種方法的缺點是,你需要確保你使用從未分隔符在任何範圍內的任何字段發生記錄。如果你確實知道這些字符串永遠不會包含某個不尋常的字符,那麼你可以使用它。否則,另一種選擇是逃避任何事件。因此,例如,如果您使用逗號作爲分隔符,則需要用替換的所有出現,然後將所有出現的\替換爲\\。當然,這不僅使您的保存邏輯複雜化,而且還使您的加載邏輯複雜化。

UPDATE

如果速度是你的主要關注,並且可以保證詞和子詞都將少於100個字符,然後閱讀的最快方法和寫入數據是寫每個字在文本文件的新行上,使用固定寬度的字段跟隨每個子字。舉例來說,如果你有五個一個最大長度,該文件可能是這個樣子:

Word Sub1 Sub2 
W2 SW1 SW2 SW3 
W3 
W4 SubWdSub2. 

正如你在這個例子看到,有四個詞(「字」,「W2」,「W3 「和」W4「),並且它們各自具有不同數量的子詞。 「Word」的子詞是「Sub1」和「Sub2」。 「W3」沒有子字,而W4有2(「SubWd」和「Sub2。」)。

所以,寫出來的這個文件,你可以做這樣的事情:

Private Sub SaveWords(filePath As String, words As List(Of Word)) 
    Const maxLength As Integer = 100 
    Using writer As New StreamWriter(filePath) 
     Dim firstWord As Boolean = True 
     For Each w As Word in words 
      If firstWord Then 
       firstWord = False 
      Else 
       writer.WriteLine() 
      End If 
      writer.Write(w.theWord.PadRight(maxLength)) 
      For Each s As SubWord In w.SubWords 
       writer.Write(s.theWord.PadRight(maxLength)) 
      Next 
     Next 
    End Using 
End Sub 
+0

爲什麼XML看起來是最好的選擇?而且,這些代碼不必要的浪費。 – Jon

+0

@Jon我推薦使用XML,因爲他試圖存儲的數據結構比簡單的一維列表更復雜。 XML更靈活,因此它可以更輕鬆地處理未來對數據結構的更改,而且它是標準的,所以其他程序員更容易理解和使用。所以,除非XML不是嚴格意義上的選擇,否則出於某種原因,我不會推薦將其排除,因爲您可能認爲它「看起來」太慢。 –

+0

@Jon至於代碼的效率,我同意,它並不是最優的。我主要是試圖清楚地演示格式,不一定是生成文件的最有效方式。顯然,直接寫入流,在項之間添加必要的分隔符會更有效率,但這樣做會使示例顯得更加複雜。我想你是對的。我應該增加另一個更有效的例子。我只是想,因爲OP沒有具體說明他們之後的效率水平,這足夠好。 –

相關問題