C#从输入文件存储字符串以进行操作和使用的最佳方法?

我有一个字符串块的文件,每个字符串都以某个关键字结尾.我目前有一个流阅读器设置,它将文件的每一行添加到列表中,直到当前块结束(行包含指示块结束的关键字).

listName.Add(lineFromFile);

每个块包含例如信息.书bookName,作者AuthorName,Journal JournalName等所以每个块假设是一个单项(书,期刊,会议等)..

现在有大约50个左右的信息块(项目)我需要一些方法来存储信息,这样我就可以操作它并存储每个作者,标题,页面等,并知道什么信息与什么项目等.

在输入这个时我想出了可能将每个Item存储为一个名为’Item’的类的对象的想法,但是对于潜在的几个作者,我不知道如何实现这个,因为我想也许使用一个用于命名变量的计数器,例如

int i = 0;
String Author[i] = "blahblah";
i++;

但据我所知,这是不允许的?所以我的问题基本上是存储每个项目的最简单/最简单的方法,以便我可以操纵字符串来存储每个项目以供以后使用.

@yamen这是一个文件的例子:

Author Bond, james
Author Smith John A
Year 1994
Title For beginners
Book Accounting
Editor Smith Joe
Editor Doe John
Publisher The University of Chicago Press
City Florida, USA
Pages 15-23
End

Author Faux, M
Author Sedge, M
Author McDreamy, L
Author Simbha, D
Year 2000
Title Medical advances in the modern world
Journal Canadian Journal of medicine
Volume 25
Pages 1-26
Issue 2
End


Author McFadden, B
Author Goodrem, G
Title Shape shifting dinosaurs
Conference Ted Vancouver
City Vancouver, Canada
Year 2012
Pages 2-6
End
最佳答案
以下是此问题的完整代码.
它是用简单直接的方法编写的.它可以被优化,没有错误检查,并且可以通过使用反射以更有效的方式编写AddData方法.但它以优雅的方式完成工作.

using System;
using System.Collections.Generic;
using System.IO;

namespace MutiItemDict
{
    class MultiDict<TKey, TValue>  // no (collection) base class
    {
        private Dictionary<TKey, List<TValue>> _data = new Dictionary<TKey, List<TValue>>();

        public void Add(TKey k, TValue v)
        {
            // can be a optimized a little with TryGetValue, this is for clarity
            if (_data.ContainsKey(k))
                _data[k].Add(v);
            else
                _data.Add(k, new List<TValue>() { v });
        }

        public List<TValue> GetValues(TKey key)
        {
            if (_data.ContainsKey(key))
                return _data[key];
            else
                return new List<TValue>();
        }
    }

    class BookItem
    {
        public BookItem()
        {
            Authors = new List<string>();
            Editors = new List<string>();
        }

        public int? Year { get; set; }
        public string Title { get; set; }
        public string Book { get; set; }
        public List<string> Authors { get; private set; }
        public List<string> Editors { get; private set; }
        public string Publisher { get; set; }
        public string City { get; set; }
        public int? StartPage { get; set; }
        public int? EndPage { get; set; }
        public int? Issue { get; set; }
        public string Conference { get; set; }
        public string Journal { get; set; }
        public int? Volume { get; set; }

        internal void AddPropertyByText(string line)
        {
            string keyword = GetKeyWord(line);
            string data = GetData(line);
            AddData(keyword, data);
        }

        private void AddData(string keyword, string data)
        {
            if (keyword == null)
                return;

            // Map the Keywords to the properties (can be done in a more generic way by reflection)
            switch (keyword)
            {
                case "Year":
                    this.Year = int.Parse(data);
                    break;
                case "Title":
                    this.Title = data;
                    break;
                case "Book":
                    this.Book = data;
                    break;
                case "Author":
                    this.Authors.Add(data);
                    break;
                case "Editor":
                    this.Editors.Add(data);
                    break;
                case "Publisher":
                    this.Publisher = data;
                    break;
                case "City":
                    this.City = data;
                    break;
                case "Journal":
                    this.Journal = data;
                    break;
                case "Volume":
                    this.Volume = int.Parse(data);
                    break;
                case "Pages":
                    this.StartPage = GetStartPage(data);
                    this.EndPage = GetEndPage(data);
                    break;
                case "Issue":
                    this.Issue = int.Parse(data);
                    break;
                case "Conference":
                    this.Conference = data;
                    break;
            }
        }

        private int GetStartPage(string data)
        {
            string[] pages = data.Split('-');
            return int.Parse(pages[0]);
        }

        private int GetEndPage(string data)
        {
            string[] pages = data.Split('-');
            return int.Parse(pages[1]);
        }

        private string GetKeyWord(string line)
        {
            string[] words = line.Split(' ');
            if (words.Length == 0)
                return null;
            else
                return words[0];
        }

        private string GetData(string line)
        {
            string[] words = line.Split(' ');
            if (words.Length < 2)
                return null;
            else
                return line.Substring(words[0].Length+1);
        }
    }

    class Program
    {
        public static BookItem ReadBookItem(StreamReader streamReader)
        {
            string line = streamReader.ReadLine();
            if (line == null)
                return null;

            BookItem book = new BookItem();
            while (line != "End")
            {
                book.AddPropertyByText(line);
                line = streamReader.ReadLine();
            }
            return book;
        }

        public static List<BookItem> ReadBooks(string fileName)
        {
            List<BookItem> books = new List<BookItem>();
            using (StreamReader streamReader = new StreamReader(fileName))
            {
                BookItem book;
                while ((book = ReadBookItem(streamReader)) != null)
                {
                    books.Add(book);
                }
            }
            return books;
        }

        static void Main(string[] args)
        {
            string fileName = "../../Data.txt";
            List<BookItem> bookList = ReadBooks(fileName);

            MultiDict<string, BookItem> booksByAutor = new MultiDict<string, BookItem>();
            bookList.ForEach(bk =>
                    bk.Authors.ForEach(autor => booksByAutor.Add(autor, bk))
                );

            string author = "Bond, james";
            Console.WriteLine("Books by: " + author);
            foreach (BookItem book in booksByAutor.GetValues(author))
            {
                Console.WriteLine("    Title : " + book.Title);
            }

            Console.WriteLine("");
            Console.WriteLine("Click to continue");
            Console.ReadKey();
        }
    }
}

我还想提一下,如果用XML表示数据,可以避免所有解析内容.
然后数据看起来像:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfBookItem >
  <BookItem>
    <Year>1994</Year>
    <Title>For beginners</Title>
    <Book>Accounting</Book>
    <Authors>
      <string>Bond, james</string>
      <string>Smith John A</string>
    </Authors>
    <Editors>
      <string>Smith Joe</string>
      <string>Doe John</string>
    </Editors>
    <Publisher>The University of Chicago Press</Publisher>
    <City>Florida, USA</City>
    <StartPage>15</StartPage>
    <EndPage>23</EndPage>
  </BookItem>
  <BookItem>
    <Year>2000</Year>
    <Title>Medical advances in the modern world</Title>
    <Authors>
      <string>Faux, M</string>
      <string>Sedge, M</string>
      <string>McDreamy, L</string>
      <string>Simbha, D</string>
    </Authors>
    <StartPage>1</StartPage>
    <EndPage>26</EndPage>
    <Issue>2</Issue>
    <Journal>Canadian Journal of medicine</Journal>
    <Volume>25</Volume>
  </BookItem>
  <BookItem>
    <Year>2012</Year>
    <Title>Shape shifting dinosaurs</Title>
    <Authors>
      <string>McFadden, B</string>
      <string>Goodrem, G</string>
    </Authors>
    <City>Vancouver, Canada</City>
    <StartPage>2</StartPage>
    <EndPage>6</EndPage>
    <Conference>Ted Vancouver</Conference>
  </BookItem>
</ArrayOfBookItem>

以及阅读它的代码:

using (FileStream stream =
    new FileStream(@"../../Data.xml", FileMode.Open,
        FileAccess.Read, FileShare.Read))
        {
            List<BookItem> books1 = (List<BookItem>)serializer.Deserialize(stream);
        }

转载注明原文:C#从输入文件存储字符串以进行操作和使用的最佳方法? - 代码日志