使用MSGReader循环解析.msg文件遇startIndex超出长度异常
问题:MSGReader遍历.msg文件时触发字符串索引异常
单文件解析.msg文件正常,但加入循环遍历文件夹内文件后报错,错误信息:startIndex cannot be larger than the length of string. Arg_ParamName_Name
预期效果:遍历9个.msg文件,更新文本框内容并将数据填充到DataTable中;实际触发上述异常。
原代码:
private void btfolder_Click(object sender, EventArgs e) { if (folderBrowserDialog1.ShowDialog() == DialogResult.OK); foreach (var file in Directory.EnumerateFiles(folderBrowserDialog1.SelectedPath, "*.msg")) { using (var msg = new MsgReader.Outlook.Storage.Message(file)) { var htmlBody = msg.BodyHtml; tbbody.Text = htmlBody; string who = tbbody.Lines[42]; string error = tbbody.Lines[46]; who = who.Substring(3, who.Length - 7); error = error.Substring(0, error.Length - 7); tbsender.Text = who; tberror.Text = error; DataTable dts = new DataTable(); DataTable dt = new DataTable(); dts.Columns.Add("Absender", typeof(string)); dts.Columns.Add("error", typeof(string)); dts.Rows.Add(who, error); dt.Merge(dts); dgvemail.DataSource = dt; } } }
问题分析:
索引越界核心原因:
- 硬编码依赖
tbbody.Lines[42]和Lines[46],不是所有邮件的HTML body都有足够行数,一旦某封邮件行数不足47,直接访问索引会报错 Substring参数未做长度校验:比如who.Length -7如果小于3,Substring(3, 长度值)的起始索引3会超过字符串实际长度,触发异常
- 硬编码依赖
其他逻辑问题:
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK);末尾多了分号,导致用户取消选择文件夹时,循环仍会执行,此时SelectedPath为空会引发额外错误- 每次循环都新建
DataTable dt,最终DataGridView只会显示最后一封邮件的数据,之前的数据会被覆盖
修改后的代码:
private void btfolder_Click(object sender, EventArgs e) { // 去掉多余分号,确保只有选择文件夹后才执行后续逻辑 if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) { // 提前初始化DataTable,避免循环内重复创建 DataTable dt = new DataTable(); dt.Columns.Add("Absender", typeof(string)); dt.Columns.Add("error", typeof(string)); dgvemail.DataSource = dt; foreach (var file in Directory.EnumerateFiles(folderBrowserDialog1.SelectedPath, "*.msg")) { using (var msg = new MsgReader.Outlook.Storage.Message(file)) { var htmlBody = msg.BodyHtml; tbbody.Text = htmlBody; string who = string.Empty; string error = string.Empty; // 先检查行数是否足够,避免索引越界 if (tbbody.Lines.Length > 46) { who = tbbody.Lines[42]; error = tbbody.Lines[46]; // 校验Substring参数,确保起始索引和长度合法 if (who.Length >= 7) who = who.Substring(3, who.Length - 7); if (error.Length >=7) error = error.Substring(0, error.Length -7); } tbsender.Text = who; tberror.Text = error; // 直接向已初始化的DataTable添加行 dt.Rows.Add(who, error); } } // 刷新DataGridView显示 dgvemail.Refresh(); } }
内容的提问来源于stack exchange,提问作者widarddd
相关产品推荐
相关产品推荐

