C#删除已保存文件后无法保存新文件:空引用异常问题
问题:删除后新建TextBox保存时触发空引用异常
功能说明
- 动态生成TextBox
- 提取TextBox文本并保存为TXT文件
- 删除文本文件
相关代码
生成TextBox按钮代码
// Generate notes int curr = 0; private void guna2Button1_Click(object sender, EventArgs e) { int top = 25; int h_p = 170; curr++; var new_note = new Guna2TextBox() { Text = "Title\n", Name = "Note" + curr, Multiline = true, AcceptsTab = true, AcceptsReturn = true, WordWrap = false, ScrollBars = ScrollBars.Vertical, Width = 220, Height = 110, BorderRadius = 8, Font = new Font("Bahnschrift", 13), ForeColor = Color.White, FillColor = ColorTranslator.FromHtml("#1E1E1E"), BorderColor = ColorTranslator.FromHtml("#2C2C2C"), Location = new Point(450,top) }; top += h_p; flowLayoutPanel1.Controls.Add(new_note); }
保存TextBox文本到文件按钮代码
// Save notes private void guna2Button7_Click(object sender, EventArgs e) { for(int j=1; j<flowLayoutPanel1.Controls.Count+1; j++) { var notes = ((Guna2TextBox)flowLayoutPanel1.Controls["Note" + j]); var messages = notes.Text; var titles = notes.Lines[0]; string notes_path = @"C:\NOTES_LOC\DATA_LOC\" + titles + ".txt"; try { if(titles != "") { using(FileStream fs = File.Create(notes_path)) { Byte[] notes_texts = new UTF8Encoding(true).GetBytes(messages); fs.Write(notes_texts,0,notes_texts.Length); } } else { MessageBox.Show("Title cannot be empty", "Flow Notes System"); } } catch (Exception eq) { MessageBox.Show(eq.ToString(),"Notes System"); } } }
删除文本文件按钮代码
// Delete notes private void guna2Button5_Click(object sender, EventArgs e) { DirectoryInfo dirs_notes_source = new DirectoryInfo(@"C:\NOTES_LOC\DATA_LOC\"); string dirs_notes = @"C:\NOTES_LOC\DATA_LOC\"; string garb_path = @"C:\NOTES_LOC\GARBAGE_LOC\"; if(flowLayoutPanel1.Controls.Count != 0) { flowLayoutPanel1.Controls.Clear(); foreach(string dir_path in Directory.GetDirectories(dirs_notes,"*",SearchOption.AllDirectories)) { Directory.CreateDirectory(dir_path.Replace(dirs_notes,garb_path)); } foreach(string retv_notes in Directory.GetFiles(dirs_notes,"*.*",SearchOption.AllDirectories)) { File.Copy(retv_notes,retv_notes.Replace(dirs_notes,garb_path),true); } foreach (FileInfo notes in dirs_notes_source.GetFiles()) { notes.Delete(); } } else { MessageBox.Show("No note found","Flow Notes System"); } }
问题描述
生成TextBox后点击保存可正常保存为TXT文件,点击删除也可正常删除文件,但删除旧文件后,生成新的TextBox并尝试保存时,弹出错误:Object reference not set to an instance of an object。
调试时发现:执行var messages = notes.Text;时触发空引用异常,提示notes为null。
异常信息
************** Exception Text ************** System.NullReferenceException: Object reference not set to an instance of an object. at FlowNotes.Form1.guna2Button7_Click(Object sender, EventArgs e) in C:\Users\USER\source\repos\FlowNotes\FlowNotes\Form1.cs:line 136 at System.Windows.Forms.Control.OnClick(EventArgs e) at Guna.UI2.WinForms.Guna2Button.OnClick(EventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
问题原因
- 计数器未重置:删除按钮仅清空了
flowLayoutPanel1中的控件,但全局变量curr的数值没有重置。比如第一次生成3个TextBox后curr=3,删除控件后再生成新的TextBox,名字会是Note4、Note5... - 保存逻辑依赖序号查找:保存代码用
for循环从Note1开始按序号查找控件,但删除后新生成的控件序号已不是从1开始,导致flowLayoutPanel1.Controls["Note" + j]找不到对应控件,返回null,访问notes.Text时触发空引用异常。
修复方案
方案1:重置计数器+优化保存逻辑
步骤1:修改删除按钮代码,重置curr
在flowLayoutPanel1.Controls.Clear();后添加curr = 0;,确保新生成的TextBox从Note1开始命名:
// Delete notes private void guna2Button5_Click(object sender, EventArgs e) { DirectoryInfo dirs_notes_source = new DirectoryInfo(@"C:\NOTES_LOC\DATA_LOC\"); string dirs_notes = @"C:\NOTES_LOC\DATA_LOC\"; string garb_path = @"C:\NOTES_LOC\GARBAGE_LOC\"; if(flowLayoutPanel1.Controls.Count != 0) { flowLayoutPanel1.Controls.Clear(); curr = 0; // 重置计数器 foreach(string dir_path in Directory.GetDirectories(dirs_notes,"*",SearchOption.AllDirectories)) { Directory.CreateDirectory(dir_path.Replace(dirs_notes,garb_path)); } foreach(string retv_notes in Directory.GetFiles(dirs_notes,"*.*",SearchOption.AllDirectories)) { File.Copy(retv_notes,retv_notes.Replace(dirs_notes,garb_path),true); } foreach (FileInfo notes in dirs_notes_source.GetFiles()) { notes.Delete(); } } else { MessageBox.Show("No note found","Flow Notes System"); } }
步骤2:优化保存代码,直接遍历控件
避免依赖控件名字的序号,直接遍历flowLayoutPanel1中的Guna2TextBox控件,逻辑更健壮:
// Save notes private void guna2Button7_Click(object sender, EventArgs e) { foreach (var control in flowLayoutPanel1.Controls) { if (control is Guna2TextBox notes) { var messages = notes.Text; var titles = notes.Lines.Length > 0 ? notes.Lines[0] : ""; string notes_path = @"C:\NOTES_LOC\DATA_LOC\" + titles + ".txt"; try { if(!string.IsNullOrEmpty(titles)) { using(FileStream fs = File.Create(notes_path)) { Byte[] notes_texts = new UTF8Encoding(true).GetBytes(messages); fs.Write(notes_texts,0,notes_texts.Length); } } else { MessageBox.Show("Title cannot be empty", "Flow Notes System"); } } catch (Exception eq) { MessageBox.Show(eq.ToString(),"Notes System"); } } } }
方案2:完全脱离计数器(更推荐)
如果不需要通过序号标识控件,生成时可以省略Name属性,直接用类型遍历的方式保存,彻底避免序号不匹配的问题。
额外优化建议
- 保存时添加标题非法字符检查(比如
\ / : * ? " < > |),避免因标题包含非法字符导致文件创建失败。 - 可以给每个TextBox添加唯一标识,但类型遍历的方式已经足够可靠,无需依赖名字查找。
内容的提问来源于stack exchange,提问作者user19335999
相关产品推荐
相关产品推荐

