附加到 csv 文件(csv 助手)在 csv 文件中提供重复条目
Appending to csv file (csv helper) gives duplicate entry in csv file
使用以下代码,我尝试将在控制台中输入的用户附加到现有的 csv 文件中。我正在使用 CSV 帮助程序并阅读了文档。
首先,我从 csv 文件加载用户并使用以下代码将它们存储在列表中:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class UserList
{
public static List<User> LoadUsersFromCSV()
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var users = csvReader.GetRecords<User>().ToList();
return users;
// try
// {
// }
// catch (CsvHelper.HeaderValidationException exception)
// {
// Console.WriteLine(exception);
// }
}
}
}
}
新用户通过此代码进入:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class RegisterManager
{
public void Register(List<User> users)
{
// Get user input
Console.WriteLine("Enter username:");
string username = Console.ReadLine();
Console.WriteLine("Enter email:");
string email = Console.ReadLine();
Console.WriteLine("Enter password:");
string password = Console.ReadLine();
Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
string userrole = Console.ReadLine();
// Create fresh instance to save input in memory
User user = new User(username, email, password, userrole);
// Adds the user to the excisting list
users.Add(user);
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
}
}
}
然后使用名为 WriteUsersToCSV 的方法将输入的用户写入现有的 csv 文件:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
// Handles CRUD within CSV files and able to save them
public class FileOperations
{
// Appends to CSV file from List
public void WriteUsersToCSV(List<User> users)
{
// Append to the file
using (var stream = File.Open("users.csv", FileMode.Append))
using (var writer = new StreamWriter(stream))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.HasHeaderRecord = false;
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}
// Writes to CSV file from List
public void WriteUsersToNewCSVFile(List<User> users)
{
using (var writer = new StreamWriter("users.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<User>();
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(users);
Console.WriteLine("New file users.csv created!");
}
}
// Reads from CSV file and displays content from it
public void ReadUsersFromCSV()
{
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
try
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var records = csvReader.GetRecords<User>().ToList();
// Loop through the List and show them in Console (connect to values in the constructor User.cs record.username etc..)
foreach (var record in records)
{
Console.WriteLine($"{record.username } | {record.email} | {record.password} | {record.userrole}");
}
}
catch (CsvHelper.HeaderValidationException exception)
{
Console.WriteLine(exception);
}
}
}
// Writes to CSV file from List
public void SaveGimpiesToCSV(List<Gimpies> gimpies)
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var writer = new StreamWriter("gimpies.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<Gimpies>();
csvWriter.WriteHeader<Gimpies>();
csvWriter.WriteRecords(gimpies);
writer.Flush();
// var result = Encoding.UTF8.GetString(mem.ToArray());
// Console.WriteLine(result);
}
}
}
}
但是当我写入现有的 csv 文件时,我再次获得了前三个用户!查看结果:
username,email,password,userrole,
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Bas,bas@bas.nl,123,admin
在这里你看到我添加了用户 Bas,但是又添加了 Inkoop 和 Verkoop 以及 Beheer。
我在代码中找不到需要删除或更改的内容。
确定这是我的 Program.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
class Program
{
static void Main(string[] args)
{
// List of default users
// List<User> users = UserList.DefaultUsers();
// Working on it... Try to read csv file first and try to read list from method in UserList.cs
// UserList ul = new UserList();
List<User> users = UserList.LoadUsersFromCSV();
// List<User> users =
// ul.LoadUsersFromCSV(users);
// Create login instance
LoginManager loginMgr = new LoginManager();
// Create stock instance
Stock stock = new Stock();
Start:
// Welcome message
Console.WriteLine("Welcome to the Gimpies Console Application! Choose 1 to login or 2 to exit this application:");
// Get input from user
string input = Console.ReadLine();
// Set to false to check if login fails or not
bool successfull = false;
while (!successfull)
{
if(input == "1")
{
Console.WriteLine("Enter your username:");
string username = Console.ReadLine();
Console.WriteLine("Enter your password:");
string password = Console.ReadLine();
foreach (User user in users)
{
if (username == user.username && password == user.password && user.userrole == "admin")
{
// Create Admin instance to be able to call methods in that class
Admin am = new Admin();
// Calling the method in Admin.cs to start Menu logic
am.AdminLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "purchase")
{
// Create Purchase instance to be able to call methods in that class
Purchase pc = new Purchase();
// Calling the method in Purchase.cs to start Menu logic
pc.PurchaseLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "sales")
{
// Create Sales instance to be able to call methods in that class
Sales sl = new Sales();
// Calling the method in Sales.cs to start Menu logic
sl.SalesLoggedIn(users);
successfull = true;
break;
}
}
if (!successfull)
{
Console.WriteLine("Your username or password is incorrect, try again !!!");
}
}
else if (input == "2")
{
Environment.Exit(-1);
}
else if (input == "3")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
goto Start;
}
else if (input == "4")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.ReadUsersFromCSV();
goto Start;
}
else
{
Console.WriteLine("Try again !!!");
break;
}
}
// // Loop over stored users within instances inside the list where users are added
// foreach (User user in users)
// {
// if(loginMgr.Login(user))
// {
// // Login successfull
// Console.WriteLine("Login user " + user.UserName);
// }
// else
// {
// // Not successfull
// }
// }
}
}
}
还有我的 GitLab 存储库:https://gitlab.com/marianydesign/gimpiesconsoleoocsvlist
我看到两个选项供您选择。确保您只实施两个选项之一。
选项 #1(您的代码试图实现的选项),您可以将新记录附加到文件数据。此选项将要求您跟踪文件中已有的内容,以便您可以排除写入文件中已有的记录。
选项#2,您可以每次用完整的用户列表覆盖文件。不附加每次只写完整的文件。
实施选项 #1:
此选项只需要更改您的 else if (input == "3")
条件。更新条件,以便它将要写入的列表与文件中已有的列表进行比较,并排除写入文件中已有的任何 Users
...
else if (input == "3")
{
FileOperations fo = new FileOperations();
// get existing users from file
List<User> userInFile = UserList.LoadUsersFromCSV();
// remove existing users from update list to create final list for writing
List<User> finalList = users.Where(u => !userInFile.Any(uf => uf.email.Equals(u.email, StringComparison.InvariantCultureIgnoreCase))).ToList();
fo.WriteUsersToCSV(users);
goto Start;
}
或
实施选项 #2:
此选项需要更改您的 WriteUsersToCSV
方法。
public void WriteUsersToCSV(List<User> users)
{
// overwrite the file each time; indicated by the `false` parameter
using (var writer = new StreamWriter("users.csv", false))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.HasHeaderRecord = false; // commented out as we write the whole file every time including the header
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}
使用以下代码,我尝试将在控制台中输入的用户附加到现有的 csv 文件中。我正在使用 CSV 帮助程序并阅读了文档。
首先,我从 csv 文件加载用户并使用以下代码将它们存储在列表中:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class UserList
{
public static List<User> LoadUsersFromCSV()
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var users = csvReader.GetRecords<User>().ToList();
return users;
// try
// {
// }
// catch (CsvHelper.HeaderValidationException exception)
// {
// Console.WriteLine(exception);
// }
}
}
}
}
新用户通过此代码进入:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class RegisterManager
{
public void Register(List<User> users)
{
// Get user input
Console.WriteLine("Enter username:");
string username = Console.ReadLine();
Console.WriteLine("Enter email:");
string email = Console.ReadLine();
Console.WriteLine("Enter password:");
string password = Console.ReadLine();
Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
string userrole = Console.ReadLine();
// Create fresh instance to save input in memory
User user = new User(username, email, password, userrole);
// Adds the user to the excisting list
users.Add(user);
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
}
}
}
然后使用名为 WriteUsersToCSV 的方法将输入的用户写入现有的 csv 文件:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
// Handles CRUD within CSV files and able to save them
public class FileOperations
{
// Appends to CSV file from List
public void WriteUsersToCSV(List<User> users)
{
// Append to the file
using (var stream = File.Open("users.csv", FileMode.Append))
using (var writer = new StreamWriter(stream))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.HasHeaderRecord = false;
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}
// Writes to CSV file from List
public void WriteUsersToNewCSVFile(List<User> users)
{
using (var writer = new StreamWriter("users.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<User>();
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(users);
Console.WriteLine("New file users.csv created!");
}
}
// Reads from CSV file and displays content from it
public void ReadUsersFromCSV()
{
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
try
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var records = csvReader.GetRecords<User>().ToList();
// Loop through the List and show them in Console (connect to values in the constructor User.cs record.username etc..)
foreach (var record in records)
{
Console.WriteLine($"{record.username } | {record.email} | {record.password} | {record.userrole}");
}
}
catch (CsvHelper.HeaderValidationException exception)
{
Console.WriteLine(exception);
}
}
}
// Writes to CSV file from List
public void SaveGimpiesToCSV(List<Gimpies> gimpies)
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var writer = new StreamWriter("gimpies.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<Gimpies>();
csvWriter.WriteHeader<Gimpies>();
csvWriter.WriteRecords(gimpies);
writer.Flush();
// var result = Encoding.UTF8.GetString(mem.ToArray());
// Console.WriteLine(result);
}
}
}
}
但是当我写入现有的 csv 文件时,我再次获得了前三个用户!查看结果:
username,email,password,userrole,
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Bas,bas@bas.nl,123,admin
在这里你看到我添加了用户 Bas,但是又添加了 Inkoop 和 Verkoop 以及 Beheer。
我在代码中找不到需要删除或更改的内容。
确定这是我的 Program.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
class Program
{
static void Main(string[] args)
{
// List of default users
// List<User> users = UserList.DefaultUsers();
// Working on it... Try to read csv file first and try to read list from method in UserList.cs
// UserList ul = new UserList();
List<User> users = UserList.LoadUsersFromCSV();
// List<User> users =
// ul.LoadUsersFromCSV(users);
// Create login instance
LoginManager loginMgr = new LoginManager();
// Create stock instance
Stock stock = new Stock();
Start:
// Welcome message
Console.WriteLine("Welcome to the Gimpies Console Application! Choose 1 to login or 2 to exit this application:");
// Get input from user
string input = Console.ReadLine();
// Set to false to check if login fails or not
bool successfull = false;
while (!successfull)
{
if(input == "1")
{
Console.WriteLine("Enter your username:");
string username = Console.ReadLine();
Console.WriteLine("Enter your password:");
string password = Console.ReadLine();
foreach (User user in users)
{
if (username == user.username && password == user.password && user.userrole == "admin")
{
// Create Admin instance to be able to call methods in that class
Admin am = new Admin();
// Calling the method in Admin.cs to start Menu logic
am.AdminLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "purchase")
{
// Create Purchase instance to be able to call methods in that class
Purchase pc = new Purchase();
// Calling the method in Purchase.cs to start Menu logic
pc.PurchaseLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "sales")
{
// Create Sales instance to be able to call methods in that class
Sales sl = new Sales();
// Calling the method in Sales.cs to start Menu logic
sl.SalesLoggedIn(users);
successfull = true;
break;
}
}
if (!successfull)
{
Console.WriteLine("Your username or password is incorrect, try again !!!");
}
}
else if (input == "2")
{
Environment.Exit(-1);
}
else if (input == "3")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
goto Start;
}
else if (input == "4")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.ReadUsersFromCSV();
goto Start;
}
else
{
Console.WriteLine("Try again !!!");
break;
}
}
// // Loop over stored users within instances inside the list where users are added
// foreach (User user in users)
// {
// if(loginMgr.Login(user))
// {
// // Login successfull
// Console.WriteLine("Login user " + user.UserName);
// }
// else
// {
// // Not successfull
// }
// }
}
}
}
还有我的 GitLab 存储库:https://gitlab.com/marianydesign/gimpiesconsoleoocsvlist
我看到两个选项供您选择。确保您只实施两个选项之一。
选项 #1(您的代码试图实现的选项),您可以将新记录附加到文件数据。此选项将要求您跟踪文件中已有的内容,以便您可以排除写入文件中已有的记录。
选项#2,您可以每次用完整的用户列表覆盖文件。不附加每次只写完整的文件。
实施选项 #1:
此选项只需要更改您的 else if (input == "3")
条件。更新条件,以便它将要写入的列表与文件中已有的列表进行比较,并排除写入文件中已有的任何 Users
...
else if (input == "3")
{
FileOperations fo = new FileOperations();
// get existing users from file
List<User> userInFile = UserList.LoadUsersFromCSV();
// remove existing users from update list to create final list for writing
List<User> finalList = users.Where(u => !userInFile.Any(uf => uf.email.Equals(u.email, StringComparison.InvariantCultureIgnoreCase))).ToList();
fo.WriteUsersToCSV(users);
goto Start;
}
或
实施选项 #2:
此选项需要更改您的 WriteUsersToCSV
方法。
public void WriteUsersToCSV(List<User> users)
{
// overwrite the file each time; indicated by the `false` parameter
using (var writer = new StreamWriter("users.csv", false))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.HasHeaderRecord = false; // commented out as we write the whole file every time including the header
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}