简体   繁体   中英

How to change values in txt file and overwrite it

I've created *.txt file with data like this:

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

In my C# app (WPF application) got this function to operate on the file:

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();
        }
    }

Now, the problem is that I can normally work on this file during program work, it changes values, can read it etc but when I turn off app (by X button) nothing happen. TXT file is untouched nor any changes are saved.

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

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

It seems to me that you must have invented a theory that any changes you make to currentDevice should, somehow, affect what's written to sw . What you're seeing here is what Karl Popper used to call "disconfirmation": Your theory predicts behavior that can be observed; you observe; the behavior is not happening. The first explanation for that is that your theory is wrong.

And that is in fact the correct explanation for what you're (not) seeing. There is absolutely no connection whatsoever between currentDevice and sw . None. It's like you're pressing buttons on the microwave in an effort to start your car. You'll be walking to work if you don't switch to another approach.

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

All you do there is change a bunch of properties on a random object, refresh your data grid, and then write a newline , a newline and nothing else , to the output stream. Why does sw.WriteLine(); , with no arguments do that? Well, it does that because that's what the designers decided it would do. There's nothing else it sanely can do, because you're not giving it anything to write. And that behavior is documented, which you would know if you had spent ten seconds reading the documentation .

If you want to write a non-empty line to a file, use one of the many, many overloads of WriteLine which are documented in the documentation . If you want to write just part of a line, use one of the many overloads of Write , which are also documented .

Something like this would be fine (I'm guessing at your field names; if you don't know what they are, maybe somebody else on StackOverflow knows what that part of your code looks like and can help you):

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();

But that's ugly. So we'll roll it into a method to hide it. This is called "refactoring".

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. 
}

...and in your event handler, call that method. Also note using statement for the StreamWriter . That disposes of it properly, which closes the file and so on. That's important.

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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM