none
How to write data of a class in a sequential file

    Question

  • Hi,

    I have created a class named Employee. In the form load event of the main form I am creating data by calling the employee class. However I need to save the data in a sequential file. I am not sure how to handle this.

    I would appreciate any help for resolution of this issue. Thanks

    CODE:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace myFile
    {
       class Employee
       {
          //Fields
          private string _name;  //employee name
          private int _id_number;  //employee id
          private string _department_id; //department id
          private string _position; //employee position
          private int _shift; //working shift
          private decimal _pay_rate; //pay rate

          //Constructor
          public Employee(string name, int idnumber, string deparment, string position, int shift, decimal pay_rate)
          {  
             _name = name;
             _id_number = idnumber;
             _department_id = deparment;
             _position = position;
             _shift = shift;
             _pay_rate = pay_rate;
          }

          public Employee(string name, int idnumber)
          {
             _name = name;
             _id_number = idnumber;
             _department_id = "";
             _position = "";
             _shift = 1;
             _pay_rate = 15.0m;
          }

          public Employee()
          {
             _name = "";
             _id_number = 0;
             _department_id = "";
             _position = "";
             _shift = 1;
             _pay_rate = 15.0m;
          }




          //Name property
          public string Name
       {
          get { return _name; }
          set { _name = value; }
       }

       public int IDNumber
       {
          get { return _id_number; }
          set { _id_number = value; }
       }

       public string Department
       {
          get { return _department_id; }
          set { _department_id = value; }
       }

       public string Position
       {
          get { return _position; }
          set { _position = value; }
       }

       public int Shift
       {
          get { return _shift; }
          set { _shift = value; }
       }

       public decimal Payrate
       {
          get{ return _pay_rate; }
          set{ _pay_rate = value; }

       }

       }
    }

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

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

          private void Form1_Load(object sender, EventArgs e)
          {
             //Create employees from the employee class
             Employee emp1 = new Employee("Jim Musumeci", 47891, "Finance", "Trainee", 1, 15);
             Employee emp2 = new Employee("Andrew Walker", 47892, "Accounting", "Supervisor", 1, 25);
             Employee emp3 = new Employee("John Summey", 47893, "Marketing", "Clerk", 1, 17);
             Employee emp4 = new Employee("Travis John", 47894, "Operation", "Clerk", 1, 17);
             Employee emp5 = new Employee("John Walker", 47895, "Accounting", "Employee Lead", 1, 20);

            

          }
       }
    }

    Thursday, December 07, 2017 4:53 PM

Answers

  • On a per-line basis, you'd need to include it as part of the string in the WriteLine call.

    var dataToWrite = ..;
    dataToWriter += "Some more stuff";

    If you want to append data to the end of the file then just use the WriteLine method as before. The writer will automatically append.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by gamaz123 Sunday, December 10, 2017 3:03 AM
    Saturday, December 09, 2017 9:59 PM
    Moderator

All replies

  • I assume that you have some sort of button or something the user will click to save the employee to a file. In that method you can save the employee data. How you save it is completely dependent upon what format you want. For a CSV file you need only write out each property that you want, separated by a comma. For XML you would want to use XmlSerializer or similar. For JSON you'll want to use a third party library. In almost all cases you'll use a StreamWriter to open the file for writing and then pass the writer to the underlying implementation. For a CSV file, which you have to write by hand, you can use the methods on the writer to write the fields.

    Here's starter code.

    void OnSave ()
    {
       //Really need to be storing employees in a list or collection - this will emulate that for now
       var employees = new List<Employee>() {
          emp1, emp2, emp3, emp4, emp5
       };  
    
       using (var writer = new StreamWriter(filename))
       {
          //Write out using the format of your choice...
    
          //CSV?
          foreach (var employee in employees)
          {
             WriteCsv(writer, employee);
          }
       };
    }
    
    void WriteCsv ( StreamWriter writer, Employee employee )
    {
       var line = $"{employee.Id},\"{employee.Name}\"";
       writer.WriteLine(line);
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, December 07, 2017 6:12 PM
    Moderator
  • Thanks for your help. Based on your advise I came up with the following code. However I am getting the below errors in the 
    following line of the code:
    List<string> employeeList = new List<string>() { emp1, emp2, emp3, emp4, emp5 };
    Severity Code Description Project File Line Suppression State
    Error CS1503 Argument 1: cannot convert from 'FInalProject.Employee' to 'string'
    Severity Code Description Project File Line Suppression State
    Error CS1950 The best overloaded Add method 'List<string>.Add(string)' for the collection initializer has some invalid arguments


    I would appreciate any help here.


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;

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

          private void Form1_Load(object sender, EventArgs e)
          {

          }

          private void saveButton_Click(object sender, EventArgs e)
          {

             //Create employees from the employee class
             Employee emp1 = new Employee("Jim Musumeci", 47891, "Finance", "Trainee", 1, 15);
             Employee emp2 = new Employee("Andrew Walker", 47892, "Accounting", "Supervisor", 1, 25);
             Employee emp3 = new Employee("John Summey", 47893, "Marketing", "Clerk", 1, 17);
             Employee emp4 = new Employee("Travis John", 47894, "Operation", "Clerk", 1, 17);
             Employee emp5 = new Employee("John Walker", 47895, "Accounting", "Employee Lead", 1, 18);
             List<string> employeeList = new List<string>() { emp1, emp2, emp3, emp4, emp5 };

          //Declare a StreamWriter variable
            StreamWriter outputFile;

             //Create a file and a Streamwriter object.

             outputFile = File.CreateText("employees.txt");

            foreach(var employee in employeeList)

                {
                outputFile.WriteLine(employee);
                }

                //Close the file
                outputFile.Close();
             }
       }
    }
    Friday, December 08, 2017 1:34 AM
  • Well, first you need the list to be of type Employee, as Michael 's reply showed you ... you have not done it that way. Try following his code exactly and I'll bet you'll have better results. Did you try it his way and it didn't work? If not, where did it fail?

    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Friday, December 08, 2017 2:11 AM
    Moderator
  • OK  that's correct. I did not follow Michael's reply totally. Anyway, I did now and still I am getting the following error. 

    Severity Code Description Project File Line Suppression State
    Error CS0103 The name 'filename' does not exist in the current context

    CODE:

    private void saveButton_Click(object sender, EventArgs e)
          {

             //Create employees from the employee class
             Employee emp1 = new Employee("Jim Musumeci", 47891, "Finance", "Trainee", 1, 15);
             Employee emp2 = new Employee("Andrew Walker", 47892, "Accounting", "Supervisor", 1, 25);
             Employee emp3 = new Employee("John Summey", 47893, "Marketing", "Clerk", 1, 17);
             Employee emp4 = new Employee("Travis John", 47894, "Operation", "Clerk", 1, 17);
             Employee emp5 = new Employee("John Walker", 47895, "Accounting", "Employee Lead", 1, 18);
          
             //The class is first stored in a list
             var employees = new List<Employee>() {emp1, emp2, emp3, emp4, emp5 };

             using (var writer = new StreamWriter(filename))
             {
                //Write the file in CSV format

                foreach (var employee in employees)
                {
                   WriteCsv(writer, employee);
                }
             }
             void WriteCsv(StreamWriter writer, Employee employee)
             {
                var line = $"{employee.IDNumber},\"{employee.Name}\"";
                writer.WriteLine(line);
             }
          }

    I appreciate your help in advance.

    Friday, December 08, 2017 3:31 AM
  • Please use the code block button in the editor to post code so it is formatted properly.

    filename is the name of your file you want to save to. It can be a literal string for test purposes or some variable you set based upon user input. It doesn't matter provided you provide the filename.


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, December 08, 2017 3:51 AM
    Moderator
  • Hello gamaz123,

    You need to learn  the serialization knowledge and deserialization knowledge. There is a good document for you.

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/serialization-and-deserialization

    The following is a good example in using Newtonsoft.Json.

    Employee emp1 = new Employee("Jim Musumeci", 47891, "Finance", "Trainee", 1, 15); Employee emp2 = new Employee("Andrew Walker", 47892, "Accounting", "Supervisor", 1, 25); Employee emp3 = new Employee("John Summey", 47893, "Marketing", "Clerk", 1, 17); Employee emp4 = new Employee("Travis John", 47894, "Operation", "Clerk", 1, 17); Employee emp5 = new Employee("John Walker", 47895, "Accounting", "Employee Lead", 1, 18); var employees = new List<Employee>() { emp1, emp2, emp3, emp4, emp5 }; //serialization string jsonstring= JsonConvert.SerializeObject(employees);

    //Deserialization var obj =JsonConvert.DeserializeObject<List<Employee>>(jsonstring);

    If you have any issues please feel free to contact me.

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 08, 2017 5:50 AM
    Moderator
  • OK I took your point to put the code in code block. However after I formatted all the six fields, the results are pretty close in the csv file but a little off. I guess I am missing sometime for the format. I am positng the code along with the result.

    How will the code change when I would like to use a text file instead of csv file for output? Thanks in advance.

    Output

    47891 Jim Musumeci,Finance Trainee,1 15
    47892 Andrew Walker,Accounting Supervisor,1 25
    47893 John Summey,Marketing Clerk,1 17
    47894 Travis John,Operation Clerk,1 17
    47895 John Walker,Accounting Employee Lead,1 18

          //Create employees from the employee class
             Employee emp1 = new Employee("Jim Musumeci", 47891, "Finance", "Trainee", 1, 15);
             Employee emp2 = new Employee("Andrew Walker", 47892, "Accounting", "Supervisor", 1, 25);
             Employee emp3 = new Employee("John Summey", 47893, "Marketing", "Clerk", 1, 17);
             Employee emp4 = new Employee("Travis John", 47894, "Operation", "Clerk", 1, 17);
             Employee emp5 = new Employee("John Walker", 47895, "Accounting", "Employee Lead", 1, 18);
          
             //The class is first stored in a list
             var employees = new List<Employee>() {emp1, emp2, emp3, emp4, emp5 };
    
             //using (var writer = new StreamWriter(filename))
             using (var writer = new StreamWriter("employee.csv"))
             {
                //Write the file in CSV format
    
                foreach (var employee in employees)
                {
                   WriteCsv(writer, employee);
                }
             }
             void WriteCsv(StreamWriter writer, Employee employee)
             {
                // var line = $"{employee.IDNumber},\"{employee.Name}\"";
                var line = $"{employee.IDNumber},\"{employee.Name},\"{employee.Department},\"{employee.Position},\"{employee.Shift},\"{employee.Payrate}\"";
                writer.WriteLine(line);
                
             }
             MessageBox.Show("Done");
          }
          
       }
    }
    

    Friday, December 08, 2017 5:55 PM
  • It doesn't matter what the name of the file is. In other words, it doesn't have to be "employee.csv". You can call it "employee.txt" and, in this case, it contains comma-separated-values so it's still "CSV" *data*.

    If that's not what you meant, could you clarify?


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Friday, December 08, 2017 7:03 PM
    Moderator
  • Thanks for your advise.  OK, I just tried the employee.txt file. It worked well but the formatting is screwed up.

    The output is as follows:

    47891,"Jim Musumeci,"Finance,"Trainee,"1,"15"
    47892,"Andrew Walker,"Accounting,"Supervisor,"1,"25"
    47893,"John Summey,"Marketing,"Clerk,"1,"17"
    47894,"Travis John,"Operation,"Clerk,"1,"17"
    47895,"John Walker,"Accounting,"Employee Lead,"1,"18"

    The first field and the fifth fields are int data type while the last field is decimal data type.

    So it seems except for the first field rest of all the fields are screwed up. It has got to do with my formatting here:

             var line = $"{employee.IDNumber},\"{employee.Name},\"{employee.Department},\"{employee.Position},\"{employee.Shift},\"{employee.Payrate}\"";

    Can he tell me where I am going wrong here? 

    Regards.

    Friday, December 08, 2017 7:31 PM
  • The line is being generated by the string literal you posted. It is using string interpolation. If you read the string, anything inside the {} is a C# expression that is evaluated at runtime. The {} literal is replaced with the string value. Everything else is put into the string explicitly.

    The shift and payrates are in double quotes in your output because in your string literal you're wrapping them in quotes using the \" literal. Remove that on each side of the expression and they won't get generated.

    var line = $"{employee.IDNumber},\"{employee.Name}\",\"{employee.Department}\",\"{employee.Position}\",{employee.Shift},{employee.Payrate}";
    


    Michael Taylor http://www.michaeltaylorp3.net

    Saturday, December 09, 2017 3:47 PM
    Moderator
  • Thanks a lot for the explanation along with the corrected format. It just worked perfect. I have one last question. I also need to append data to the same comma delimited file using user input from a form. 

    So if I have the final expression to append as:

    myName + "," + myIdNum + "," + myPosition + "," + myDeptId + "," + myShift + "," + myPayRate

    which translates to a sample data as:

    Jake Smith,223344,Analyst,Finance,2,20.5

    What code change to the streamwriter code block will allow me to append to the already saved file?

    Thanks in advance.

    Saturday, December 09, 2017 9:53 PM
  • On a per-line basis, you'd need to include it as part of the string in the WriteLine call.

    var dataToWrite = ..;
    dataToWriter += "Some more stuff";

    If you want to append data to the end of the file then just use the WriteLine method as before. The writer will automatically append.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by gamaz123 Sunday, December 10, 2017 3:03 AM
    Saturday, December 09, 2017 9:59 PM
    Moderator
  • Thanks. I tweaked part of your previous code as below:

     StreamWriter writer;
             writer = File.AppendText("employee.txt");
             var line = $"{myIdNum},\"{myName}\",\"{myDeptId}\",\"{myPosition}\",{myShift},{myPayRate}";
             writer.WriteLine(line);
             writer.Close();
             MessageBox.Show("Done");  

    With that change the append is working very well.

    Regards.

    Sunday, December 10, 2017 3:08 AM