【问题标题】:How to change values in txt file and overwrite it如何更改txt文件中的值并覆盖它
【发布时间】:2017-01-01 22:01:09
【问题描述】:

我创建了 *.txt 文件,其中包含如下数据:

deviceid,model,availability,renterID,renterName,reneterSurname,OS
0001,iPhone_5S,false,002,John,Dowland,iOS-7.1.2
0002,GalaxyS3,false,002,Amadeus,Mozart,Android-4.3.2

在我的 C# 应用程序(WPF 应用程序)中得到了这个函数来操作文件:

private void rentSaveButton_Click(object sender, RoutedEventArgs e)
    {
        StreamWriter sw = new StreamWriter(@"D:\deviceLib.txt", true);

        var currentUser = _list.Where(u => u.Id == int.Parse(userIDTextBox.Text)).FirstOrDefault();

        var currentDevice = _list2.Where(i => i.deviceId == int.Parse(deviceIDTextBox.Text)).FirstOrDefault();
        if (currentDevice != null &&  currentUser != null)
        {
            currentDevice.Availability = false;
            currentDevice.rentId = currentUser.Id;
            currentDevice.rentName = currentUser.Name;
            currentDevice.rentSurname = currentUser.Surname;
            dataGridDeviceList.Items.Refresh();
            sw.WriteLine();
            sw.Close();                
            MessageBox.Show("Rent done. Thanks!");
            tabControl.SelectedItem = mainTab;
        }
        else
        {
            MessageBox.Show("We don't have such device. Sorry :( ");
            userIDTextBox.Clear();
            deviceIDTextBox.Clear();
        }
    }

现在,问题是我可以在程序工作期间正常处理此文件,它会更改值,可以读取它等,但是当我关闭应用程序(通过 X 按钮)时,什么也没有发生。 TXT 文件保持不变,也没有保存任何更改。

【问题讨论】:

  • 所以如果你关闭你的应用程序,你有没有点击保存?你查过这段代码了吗?
  • 您是否尝试设置断点?通常前面的行是相同的,因为new StreamWriter(@"D:\deviceLib.txt", true) 告诉流写入器在目标文件中追加新行。
  • 这是一个 CSV 文件,treat it as CSV

标签: c# file text overwrite


【解决方案1】:

您没有在文件中写入任何内容。

sw.WriteLine(); // you need to pass a string in to this function

【讨论】:

  • 您还应该为您的流写入器使用 using 语句。
【解决方案2】:

在我看来,您一定是发明了一个理论,即您对currentDevice 所做的任何更改都会以某种方式影响写入sw 的内容。你在这里看到的是卡尔·波普尔(Karl Popper)过去所说的“不证实”:你的理论预测了可以观察到的行为;你观察;行为没有发生。对此的第一个解释是你的理论是错误的。

这实际上是对您(未)看到的内容的正确解释。 currentDevicesw 之间绝对没有任何联系。没有。就像您按下微波炉上的按钮以启动汽车一样。如果您不改用另一种方法,您将步行上班。

currentDevice.Availability = false;
currentDevice.rentId = currentUser.Id;
currentDevice.rentName = currentUser.Name;
currentDevice.rentSurname = currentUser.Surname;
dataGridDeviceList.Items.Refresh();
sw.WriteLine();
sw.Close();

你所做的只是改变一个随机对象的一堆属性,刷新你的数据网格,然后写换行符换行符,没有别的,输出流。为什么sw.WriteLine();,没有参数这样做?嗯,它这样做是因为设计师决定这样做。它没有其他任何东西可以 做,因为你没有给它任何可写的东西。并且记录了该行为,如果您花费了十秒钟 reading the documentation,您就会知道这一点。

如果您想将非空行写入文件,请使用众多overloads of WriteLine which are documented in the documentation 之一。如果您只想写一行的部分,请使用the many overloads of Write, which are also documented 之一。

这样就可以了(我猜你的字段名称;如果你不知道它们是什么,也许 StackOverflow 上的其他人知道你的代码的那部分是什么样子并且可以帮助你):

currentDevice.Availability = false;
currentDevice.rentId = currentUser.Id;
currentDevice.rentName = currentUser.Name;
currentDevice.rentSurname = currentUser.Surname;

//  Write fields in desired order of appearance in the file. 
sw.Write(currentDevice.deviceID);
//  There are many far superior ways to write a comma to the file, 
//  and I'll hear about all of them in comments, but we're keeping 
//  it as simple as possible for the moment.  
sw.Write(",");
sw.Write(currentDevice.model);
sw.Write(",");

//  Properties you just set
sw.Write(currentDevice.Availability);
sw.Write(",");
sw.Write(currentDevice.rentID);
sw.Write(",");
sw.Write(currentDevice.rentName);
sw.Write(",");
sw.Write(currentDevice.rentSurname);
sw.Write(",");

sw.Write(currentDevice.OS);

//  NOW write a newline.
sw.WriteLine();

但这很难看。所以我们将它滚动到一个隐藏它的方法中。这称为“重构”。

public void WriteDeviceStateToStream(StreamWriter stream, WhateverTheDeviceClassIs device)
{
    //  Write fields in desired order of appearance in the file. 
    stream.Write(device.deviceID);
    //  There are many far superior ways to write a comma to the file, 
    //  and I'll hear about all of them in comments, but we're keeping 
    //  it as simple as possible for the moment.  
    stream.Write(",");
    stream.Write(device.model);
    stream.Write(",");

    //  Properties you just set
    stream.Write(device.Availability);
    stream.Write(",");
    stream.Write(device.rentID);
    stream.Write(",");
    stream.Write(device.rentName);
    stream.Write(",");
    stream.Write(device.rentSurname);
    stream.Write(",");

    stream.Write(device.OS);

    //  NOW write a newline.
    stream.WriteLine();

    //  DO NOT close the stream here. The stream belongs to the caller; make no 
    //  assumptions about what he plans to do with it next. 
}

...并在您的事件处理程序中,调用该方法。另请注意StreamWriterusing 语句。这会正确处理它,从而关闭文件等等。这很重要。

private void rentSaveButton_Click(object sender, RoutedEventArgs e)
{
    using (StreamWriter sw = new StreamWriter(@"D:\deviceLib.txt", true))
    {
        var currentUser = _list.Where(u => u.Id == int.Parse(userIDTextBox.Text)).FirstOrDefault();

        var currentDevice = _list2.Where(i => i.deviceId == int.Parse(deviceIDTextBox.Text)).FirstOrDefault();
        if (currentDevice != null &&  currentUser != null)
        {
            currentDevice.Availability = false;
            currentDevice.rentId = currentUser.Id;
            currentDevice.rentName = currentUser.Name;
            currentDevice.rentSurname = currentUser.Surname;
            dataGridDeviceList.Items.Refresh();

            //  Call write method
            WriteDeviceStateToStream(sw, currentDevice);

            //  The user's going to get real tired of this messagebox real fast. 
            MessageBox.Show("Rent done. Thanks!");
            tabControl.SelectedItem = mainTab;
        }
        else
        {
            MessageBox.Show("We don't have such device. Sorry :( ");
            userIDTextBox.Clear();
            deviceIDTextBox.Clear();
        }
    }
}

【讨论】:

  • 我认为要么重写 ToString,要么创建一个像 ToStringForFile() 这样的新方法更有意义。对我来说,对流进行所有这些单独的写调用似乎很笨拙。当然,您也可以了解为什么我们将它们作为逗号分隔值存储在文件中...
  • 同意,字符串化方法会更加灵活。
  • 字符串化符可以更短:object[] elements = new[] { x.deviceid, x.model, x.availability, x.renterID, x.renterName, x.reneterSurname, x.OS }; sw.WriteLine (string.Join (",", elements));
猜你喜欢
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 2017-09-14
  • 1970-01-01
  • 2019-07-31
  • 2012-11-23
  • 1970-01-01
相关资源
最近更新 更多