读取保存在文本文件中的多个记录

时间:2014-04-03 22:09:01

标签: c# forms user-interface

基本上我让用户打开一个当前格式化的文本文档。

  

Burger.jpg,Double Down KFC,Food,30/06/95,这是一个汉堡

然后将信息分成数组,然后分成变量,然后分成文本框。

显然,如果我想要多个记录,我可能需要以不同的方式对其进行格式化(这就是我需要帮助的地方)

但是,如果我有这样的话,那么从文本文件中获取这些记录并将它们分开存储的最有效方法是让我可以浏览它们。例如,我的表单上有一个组合框。选择记录后,表单将填充该记录数据。

多条记录:

  

Burger.jpg,Double Down KFC,Food,30/06/95,这是一个汉堡

     

Person.jpg,Smile,People,23/06/95,这是一个人

这是我目前为此部分编写的代码。

private void LoadFile()
{
    StreamReader reader = new StreamReader(fileName);

    content = reader.ReadLine();

    doc = content.Split(',');

    filename = Convert.ToString(doc[0]);
    fileNameTextBox.Text = doc[0];

    description = doc[1];
    descriptionTextBox.Text = doc[1];

    category = doc[2];
    categoryComboBox.Text = doc[2];

    //dateTaken = Convert.ToDouble(doc[3]);
    dateTakenTextBox.Text = doc[3];

    comments = doc[4];
    commentsTextBox.Text = doc[4];
}

此代码目前有效,但仅适用于第一条记录,因为它使用的是一个数组,我显然需要多种方式来存储其他行。

我认为最好的选择,如果我要猜测的是使用某种类型的List与生成记录的类,但这就是我被困住并需要帮助的地方。 (通常我在这里的问题得到了落实,因为如果这是案例评论我不够简洁,我会尝试改变我的问题。

谢谢大家。

4 个答案:

答案 0 :(得分:1)

创建一个类似于您的数据行的类,然后遍历该文件,进行拆分并使用拆分数据构建新的类实例。将其存储在List<>中(或其他一些适当的结构)确保您存储它以便以后可以引用它。在加载和解析文件时不要改变你的UI(正如迈克所建议的那样),同时迈克建议你需要阅读,直到达到EOF(网上有很多这样的例子)MSDN example

此外,streamreader实现了IDisposable,因此您需要将其丢弃,或将其包装在using语句中进行清理。

示例类,您甚至可以将行作为构造函数参数传递:

public class LineItem
{
    public string FileName { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public DateTime DateTaken { get; set; }
    public string Comments { get; set; }

    public LineItem(string textRow)
    {
        if (!string.IsNullOrEmpty(textRow) && textRow.Contains(','))
        {
            string[] parts = textRow.Split(',');
            if (parts.Length == 5)
            {
                // correct length
                FileName = parts[0];
                Description = parts[1];
                Category = parts[2];
                Comments = parts[4];

                // this needs some work
                DateTime dateTaken = new DateTime();
                if (DateTime.TryParse(parts[3], out dateTaken))
                {
                    DateTaken = dateTaken;
                }
            }
        }
    }
}

答案 1 :(得分:1)

我会创建一个包含记录信息的类

public class ImageInfo
{
    public string FileName { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public DateTime Date { get; set; }
    public string Comments { get; set; }

    public override string ToString()
    {
        return FileName;
    }
}

现在您可以编写一个返回图像信息的方法

public List<ImageInfo> ReadImageInfos(string fileName)
{          
    string[] records = File.ReadAllLines(fileName);
    var images = new List<ImageInfo>(records.Length);
    foreach (string record in records) {
        string[] columns = record.Split(',');
        if (columns.Length >= 5) {
            var imageInfo = new ImageInfo();
            imageInfo.FileName = columns[0];
            imageInfo.Description = columns[1];
            imageInfo.Category = columns[2];

            DateTime d;
            if (DateTime.TryParseExact(columns[3], "dd/MM/yy", 
                CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
            {
                imageInfo.Date = d;
            }

            imageInfo.Comments = columns[4];

            images.Add(imageInfo);
        }
    }
    return images;
}

现在,您可以使用以下其中一个记录填充文本框

List<ImageInfo> images = ReadImageInfos(fileName);
if (images.Count > 0) {
    ImageInfo image = images[0];
    fileNameTextBox.Text = image.FileName;
    descriptionTextBox.Text = image.Description;
    categoryComboBox.Text = image.Category;
    dateTakenTextBox.Text = image.Date.ToShortDateString();
    commentsTextBox.Text = image.Comments;
}

这种方法的优点是读取和显示记录的两个操作是分开的。这样可以更容易理解和修改代码。


如果您覆盖ImageInfo类中的ComboBox方法,则可以直接将ListBox个对象添加到ToStringImageInfo,而不是添加文件名。

public override string ToString()
{
    return FileName;
}

将项目添加到组合框中,如下所示:

myComboBox.Items.Add(image); // Where image is of type ImageInfo.

您可以使用以下选项检索当前选定的项目:

ImageInfo image = (ImageInfo)myComboBox.SelectedItem;

您很可能会在SelectedIndexChanged事件处理程序中执行此操作。

void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    ImageInfo image = (ImageInfo)myComboBox.SelectedItem;
    myTextBox.Text = image.FileName;
}

答案 2 :(得分:0)

您的代码没有遍历文件中的记录。

您希望继续阅读,直到文件结束。

while (content != eof)
{
    // split content
    // populate text boxes
}

但是这会在每次循环时覆盖你的文本框。 此外,您希望分离代码 - 不要将I / O进程与更新UI的代码混合在一起。 方法的名称意味着您正在加载文件,但该方法远不止于此。我建议更改方法来读取文件,将每个记录拆分成一个类对象,然后将其存储到一个数组中 - 并返回该数组。

单独的方法将采用该数组并填充表格或网格或UI中的任何内容。理想情况下,您将gridview绑定到数组。

答案 3 :(得分:0)

如果您保留所有条目:

name,food,type,blah blah
name,food,type,blah blah

您可以在代码中添加另一个拆分:

line = content.Split('\n');
foreach (line in filename)
{
    doc = line.Split(',');
    //do stuff...

对于字符串多个条目的选项,我使用的方法是实现模型列表:

class ModelName
{
    string Name { get; set; }
    string foodType { get; set; }
    //etc...

    public void ModelName()
    {
        Name = null;
        foodType = null;
        //etc...
    }
}

List<Model> ModelList;
foreach (line in filename)
{
    doc = line.Split(',');
    Model.Name = doc[1];
    //etc...

并为每种类型的条目(人或食物)设置不同的列表和不同的模型