使用二进制文件的 C# Winforms 登录表单
C# Winforms Log-In Form using Binary File
我目前正在做一个学校项目,该项目将采用您的经典 log-in/register 形式。该项目要求我们包含一个二进制文件来 'securely' 存储每个用户的信息,例如用户名、密码等。
我在新用户注册时成功地将其信息写入名为 "users" 的二进制文件,然后我成功地将其读回富文本框。 (这只是为了让我知道所有内容都在回读)。
当这个用户被输入到表单的登录部分时,我也能够成功识别最后一个注册用户,但我无法识别任何其他用户的信息。
我的注册代码(例如,当点击注册按钮时)
private void btnRegister_Click(object sender, EventArgs e)
{
//Try - Catch Statements
//Try to set the forename
try
{
newUser.Forename = txtForename.Text;
errForename.Icon = Properties.Resources.CorrectIcon;
errForename.SetError(txtForename, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errForename.SetError(txtForename, exc.MessageM);
}
//Try to set the surname
try
{
newUser.Surname = txtSurname.Text;
errSurname.Icon = Properties.Resources.CorrectIcon;
errSurname.SetError(txtSurname, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errSurname.SetError(txtSurname, exc.MessageM);
}
//Try to set the password
try
{
newUser.Password = txtPasswordR.Text;
errPasswordR.Icon = Properties.Resources.CorrectIcon;
errPasswordR.SetError(txtPasswordR, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errPasswordR.SetError(txtPasswordR, exc.MessageM);
}
// These lines of code set the User class
if (newUser.Password != null )
{
newUser.Forename = txtForename.Text;
newUser.Surname = txtSurname.Text;
newUser.Username = txtUsernameR.Text;
newUser.Password = txtPasswordR.Text;
FileStream fileStream = new FileStream("../../Textfiles/users.bin", FileMode.Append);
BinaryWriter binaryWriter = new BinaryWriter(fileStream);
{
binaryWriter.Write(newUser.Forename);
binaryWriter.Write(newUser.Surname);
binaryWriter.Write(newUser.Username);
binaryWriter.Write(newUser.Password);
}
binaryWriter.Flush();
binaryWriter.Close();
}
}
我的读取Bin文件的代码
public bool ReadFromBin(string a, string b)
{
bool okFlag = false;
FileStream fileStream = File.OpenRead("../../TextFiles/users.bin");
BinaryReader binaryReader = new BinaryReader(fileStream);
while (binaryReader.PeekChar() != -1)
{
newUser.Forename = binaryReader.ReadString();
newUser.Surname = binaryReader.ReadString();
newUser.Username = binaryReader.ReadString();
newUser.Password = binaryReader.ReadString();
if ((newUser.Username == a) && (newUser.Password == b))
okFlag = true;
else
okFlag = false;
}
binaryReader.Close();
return okFlag;
}
最后是非常简单的登录代码
private void btnLogIn_Click(object sender, EventArgs e)
{
if(this.ReadFromBin(txtUsername.Text, txtPassword.Text) == false)
{
MessageBox.Show("Not registered!");
}
else
{
MessageBox.Show("Registered!");
Game frm = new Game(newUser);
frm.Show();
}
}
我的理解是问题很可能出在 ReadFromBin 方法中包含的 while 循环中,我只是不确定如何解决它。谢谢!
我相信你的问题是在条件。
您始终在测试用户是否为 (a,b),并且仅当最后一个用户为 (a,b) 时您的代码才有效。
您需要更改以下内容:
public bool ReadFromBin(string a, string b)
{
bool okFlag = false;
FileStream fileStream = File.OpenRead("../../TextFiles/users.bin");
BinaryReader binaryReader = new BinaryReader(fileStream);
while (binaryReader.PeekChar() != -1)
{
newUser.Forename = binaryReader.ReadString();
newUser.Surname = binaryReader.ReadString();
newUser.Username = binaryReader.ReadString();
newUser.Password = binaryReader.ReadString();
if ((newUser.Username == a) && (newUser.Password == b))
{
okFlag = true;
break;
}
}
binaryReader.Close();
return okFlag;
}
这是问题所在:
if ((newUser.Username == a) && (newUser.Password == b))
okFlag = true;
else
okFlag = false;
对于文件中的 每个 条目,该代码是 运行。因此,如果第一个条目的 okFlag
设置为 true
,但还有其他条目,那么它是无关紧要的 - 因为其他条目将被设置为 false
。
最简单的解决方法是对 FileStream
和 BinaryReader
使用 using
语句,这样您就不需要 Close
调用,然后只需完全删除 okFlag
,如果遇到匹配的条目,只需 returning true
:
if (newUser.Username == a && newUser.Password == b)
{
return true;
}
然后在循环之后放一个 return false
,所以如果 no 条目匹配,你只会 return false。
当然,您确实不应该将密码放在文件中,但那是另一回事...
请注意,使用 using
语句的原因不仅仅是为了解决此问题 - 您想要关闭流并 reader 即使抛出异常也是如此。你应该总是在这样的场景中使用using
语句,你打开一个资源,使用它,然后关闭它 - 你想让关闭操作发生无论您在使用资源时是否抛出异常。
我目前正在做一个学校项目,该项目将采用您的经典 log-in/register 形式。该项目要求我们包含一个二进制文件来 'securely' 存储每个用户的信息,例如用户名、密码等。
我在新用户注册时成功地将其信息写入名为 "users" 的二进制文件,然后我成功地将其读回富文本框。 (这只是为了让我知道所有内容都在回读)。
当这个用户被输入到表单的登录部分时,我也能够成功识别最后一个注册用户,但我无法识别任何其他用户的信息。
我的注册代码(例如,当点击注册按钮时)
private void btnRegister_Click(object sender, EventArgs e)
{
//Try - Catch Statements
//Try to set the forename
try
{
newUser.Forename = txtForename.Text;
errForename.Icon = Properties.Resources.CorrectIcon;
errForename.SetError(txtForename, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errForename.SetError(txtForename, exc.MessageM);
}
//Try to set the surname
try
{
newUser.Surname = txtSurname.Text;
errSurname.Icon = Properties.Resources.CorrectIcon;
errSurname.SetError(txtSurname, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errSurname.SetError(txtSurname, exc.MessageM);
}
//Try to set the password
try
{
newUser.Password = txtPasswordR.Text;
errPasswordR.Icon = Properties.Resources.CorrectIcon;
errPasswordR.SetError(txtPasswordR, "OK");
}
// catch the exception error if one is raised and place the message
//into the ErrorProvider
catch (NewException exc)
{
errPasswordR.SetError(txtPasswordR, exc.MessageM);
}
// These lines of code set the User class
if (newUser.Password != null )
{
newUser.Forename = txtForename.Text;
newUser.Surname = txtSurname.Text;
newUser.Username = txtUsernameR.Text;
newUser.Password = txtPasswordR.Text;
FileStream fileStream = new FileStream("../../Textfiles/users.bin", FileMode.Append);
BinaryWriter binaryWriter = new BinaryWriter(fileStream);
{
binaryWriter.Write(newUser.Forename);
binaryWriter.Write(newUser.Surname);
binaryWriter.Write(newUser.Username);
binaryWriter.Write(newUser.Password);
}
binaryWriter.Flush();
binaryWriter.Close();
}
}
我的读取Bin文件的代码
public bool ReadFromBin(string a, string b)
{
bool okFlag = false;
FileStream fileStream = File.OpenRead("../../TextFiles/users.bin");
BinaryReader binaryReader = new BinaryReader(fileStream);
while (binaryReader.PeekChar() != -1)
{
newUser.Forename = binaryReader.ReadString();
newUser.Surname = binaryReader.ReadString();
newUser.Username = binaryReader.ReadString();
newUser.Password = binaryReader.ReadString();
if ((newUser.Username == a) && (newUser.Password == b))
okFlag = true;
else
okFlag = false;
}
binaryReader.Close();
return okFlag;
}
最后是非常简单的登录代码
private void btnLogIn_Click(object sender, EventArgs e)
{
if(this.ReadFromBin(txtUsername.Text, txtPassword.Text) == false)
{
MessageBox.Show("Not registered!");
}
else
{
MessageBox.Show("Registered!");
Game frm = new Game(newUser);
frm.Show();
}
}
我的理解是问题很可能出在 ReadFromBin 方法中包含的 while 循环中,我只是不确定如何解决它。谢谢!
我相信你的问题是在条件。
您始终在测试用户是否为 (a,b),并且仅当最后一个用户为 (a,b) 时您的代码才有效。
您需要更改以下内容:
public bool ReadFromBin(string a, string b)
{
bool okFlag = false;
FileStream fileStream = File.OpenRead("../../TextFiles/users.bin");
BinaryReader binaryReader = new BinaryReader(fileStream);
while (binaryReader.PeekChar() != -1)
{
newUser.Forename = binaryReader.ReadString();
newUser.Surname = binaryReader.ReadString();
newUser.Username = binaryReader.ReadString();
newUser.Password = binaryReader.ReadString();
if ((newUser.Username == a) && (newUser.Password == b))
{
okFlag = true;
break;
}
}
binaryReader.Close();
return okFlag;
}
这是问题所在:
if ((newUser.Username == a) && (newUser.Password == b))
okFlag = true;
else
okFlag = false;
对于文件中的 每个 条目,该代码是 运行。因此,如果第一个条目的 okFlag
设置为 true
,但还有其他条目,那么它是无关紧要的 - 因为其他条目将被设置为 false
。
最简单的解决方法是对 FileStream
和 BinaryReader
使用 using
语句,这样您就不需要 Close
调用,然后只需完全删除 okFlag
,如果遇到匹配的条目,只需 returning true
:
if (newUser.Username == a && newUser.Password == b)
{
return true;
}
然后在循环之后放一个 return false
,所以如果 no 条目匹配,你只会 return false。
当然,您确实不应该将密码放在文件中,但那是另一回事...
请注意,使用 using
语句的原因不仅仅是为了解决此问题 - 您想要关闭流并 reader 即使抛出异常也是如此。你应该总是在这样的场景中使用using
语句,你打开一个资源,使用它,然后关闭它 - 你想让关闭操作发生无论您在使用资源时是否抛出异常。