Click here to Skip to main content
15,881,709 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My app is able to add "users" to a text file, when I click on "Add User" button, a line is appended to my text file. But if I want to remove an user? That would be accomplished by writing the username in a textBox and click on "Remove User" button, but I don't know what to use to remove the line from the textFile.

For example, my textFile that is storing usernames has:
User01<br />
User02<br />
ChrisCreateBoss<br />
ChrisHD22<br />


And if I want to remove ChrisHD22, I have to write ChrisHD22 in my textBox1 and when Remove button is clicked, a streamWriter would remove the line that says ChrisHD22 and let the other lines untouched.

I'm currently using this to check if the username exists in the text file:
C#
if(File.ReadLines(usersPath).Contains(usertxt2.Text))
           {
              // What can I write here?
           }


If I wasn't clear please let me know.
Thanks in Advance - CCB
Posted
Updated 6-Mar-15 15:22pm
v2
Comments
BillWoodruff 6-Mar-15 23:29pm    
Using a plain text file, and strings, as a database, here, is a real waste. I'd suggest you start working with Classes, and then serialize the Classes as needed.

It's not hard to do, and if you ask, I'll be happy to show you how.
ChrisCreateBoss 7-Mar-15 17:04pm    
I have not used classes many times, and I have not learned too much about them, but I would really appreciate it if you can teach me how to use make and use them. And thanks for the suggestion.
BillWoodruff 8-Mar-15 5:55am    
I'll add a solution today or tomorrow. cheers, Bill
ChrisCreateBoss 8-Mar-15 12:25pm    
Ok, I'll wait for your solution. Thank you!

Loop over all lines and create a copy of the original lines where you leave away the matching lines. Something like this in LINQ (or you may implement it as foreach loop too with some nested if):
C#
string item = usertxt2.Text.Trim();
var lines = File.ReadAllLines(usersPath).Where(line => line.Trim() != item).ToArray();
File.WriteAllLines(usersPath, lines);

Cheers
Andi
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 1-Apr-15 12:23pm    
Easy enough, a 5.
—SA
Andreas Gieriet 1-Apr-15 16:09pm    
Thanks for your 5!
You seem to scan many answers today! ;-)
Cheers
Andi
Sergey Alexandrovich Kryukov 1-Apr-15 16:54pm    
You are welcome — it always related to something, I don't get time to scan answers just for voting, but it's good to use a chance to vote for a good post.
—SA
MrRenew 7-Apr-24 11:03am    
thanks man was easiest solution
Using the 'DataContract and 'DataMember Attributes in System.Runtime.Serialization you can easily serialize and de-serialize a Class. The code shown here is as simple as possible, to illustrate the techniques involved.

Start with:

1. A Windows Forms Project with:

a. a TextBox, 'textBox1
b. ListBox, 'listBox1
c. 4 buttons: 'btnAdd, 'btnDelete, 'btnSave, 'btnLoad

2. This simple class:
C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace March8_SimpleDB
{
    [DataContract]
    public class Users
    {
        [DataMember]
        public List<string> UserList { set; get; }
        
        [DataMember]
        public string FileLocation { set; get; }

        private static DataContractSerializer theSerializer;

        public Users()
        {
            UserList = new List<string>();

            // default write location
            FileLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            FileLocation = Path.Combine(FileLocation, @"DefaultUsersFile.xml");
        }

        public void Add(string newUser)
        {
            UserList.Add(newUser);
        }

        public void Remove(string xUser)
        {
            UserList.Remove(xUser);
        }

        public bool Contains(string user)
        {
            return (UserList.Contains(user));
        }

        public static void Serialize(Users theUsers)
        {
            if(theSerializer == null) theSerializer = new DataContractSerializer(typeof(Users));

            try
            {
                using (FileStream stream = new FileStream(theUsers.FileLocation, FileMode.Create))
                {
                    theSerializer.WriteObject(stream, theUsers);
                }
            }
            catch (Exception)
            {
                throw new InvalidDataContractException("Can't save file to: " + theUsers.FileLocation);
            }

            MessageBox.Show("file successfully saved");
        }

        public static Users DeSerialize(Users theUsers)
        {
            // lazy load
            if (theSerializer == null) theSerializer = new DataContractSerializer(typeof(Users));

            Users result = null;

            using (FileStream stream = new FileStream(theUsers.FileLocation, FileMode.Open))
            {
                try
                {
                    result = (Users) theSerializer.ReadObject(stream);
                    theUsers.UserList = result.UserList;
                }
                catch (Exception)
                {
                    throw new InvalidDataContractException("Can't read file at: " + theUsers.FileLocation);
                }          
            }

            MessageBox.Show("file read successfully");

            return result;
        } 
    }
}</string></string>
Here's how you would serialize and de-serialize this class in the "main Form:"
C#
using System;
using System.Windows.Forms;

namespace March8_SimpleDB
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Users TheUsers;

        private void Form1_Load(object sender, EventArgs e)
        {
            TheUsers = new Users();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            string text = textBox1.Text;

            // no valid entry ?
            if (string.IsNullOrWhiteSpace(text)) return;

            // already have this User name ?
            if (TheUsers.Contains(text)) return;

            TheUsers.Add(text);

            listBox1.Items.Add(text);
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            object selection = listBox1.SelectedItem;

            // no selection ?
            if (selection == null) return;

            string text = selection.ToString();

            TheUsers.Remove(text);
            listBox1.Items.Remove(selection);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            TheUsers.UserList.Clear();

            foreach (var itm in listBox1.Items)
            {
                TheUsers.Add(itm.ToString());
            }

            Users.Serialize(TheUsers);
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            Users.DeSerialize(TheUsers);

            listBox1.Items.Clear();

            foreach (string user in TheUsers.UserList)
            {
                listBox1.Items.Add(user);
            }
        }
    }
}
Notes:

1. Yes, you can use 'DataContract/'DataMember to serialize a Class that inherits from a Generic List, or Dictionary, but in order to do that a work-around is required because the Serializer will write only the Items in the LIst or KeyValue Pairs in the Dictionary, and will ignore any other Fields/Properties marked with 'DataMember.

2. Static Class members will be ignored by the Serilializer.

3. You can serialize Fields with 'DataContract; I think it's better practice, for many reasons, to get in the habit of using Properties rather than Fields. Keep in mind that the upcoming C# 6.0 will allow easy in-line initialization of Properties.

Comments, suggestions, welcome.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900