使用FileStream时从CSV读取变量引发路径非法字符异常
解决从CSV读取time变量导致路径非法字符异常的问题
你遇到的问题本质是从CSV读取的time字符串包含肉眼不可见的特殊控制字符——比如换行符(\n)、回车符(\r)、制表符(\t),甚至UTF-8的BOM标记,这些字符在MessageBox里不会显示,但会被FileStream判定为路径非法字符。
验证问题的方法
可以先把time变量的每个字符的ASCII码打出来,确认是否有异常:
foreach (char c in time) { MessageBox.Show($"字符: '{c}' | ASCII码: {(int)c}"); }
正常的字母/数字ASCII码在32-126之间,低于32的都是控制字符(比如\r是13,\n是10),这些就是罪魁祸首。
直接解决方案:清理time字符串
在拼接路径前,先移除所有非打印字符和非法路径字符:
// 移除所有控制字符(换行、回车等) string cleanTime = Regex.Replace(time, @"[\p{C}]", string.Empty); // 再移除系统定义的非法路径字符 foreach (char invalidChar in Path.GetInvalidPathChars()) { cleanTime = cleanTime.Replace(invalidChar.ToString(), string.Empty); } // 改用Path.Combine拼接路径,自动处理分隔符问题 string pathSave = Path.Combine(Path.GetTempPath(), $"disk{cleanTime}.vhd");
额外优化建议
- CSV读取时注意编码:如果CSV是用UTF-8+BOM保存的,读取时要指定编码为
Encoding.UTF8,避免把BOM字符(\uFEFF)读进字符串里。 - 提前校验路径:在创建FileStream前,用
Path.IsPathRooted(pathSave)和File.Exists(pathSave)做前置检查,提前排查问题。
修改后的完整代码片段:
private void FileEncrypt(string outFile, string password, string time) { byte[] salt = GenerateRandomSalt(); FileStream fsCrypt = new FileStream(outFile, FileMode.Create); byte[] passwordBytes = Encoding.UTF8.GetBytes(password); RijndaelManaged AES = new RijndaelManaged(); AES.KeySize = 256; AES.BlockSize = 128; AES.Padding = PaddingMode.PKCS7; Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Mode = CipherMode.CFB; fsCrypt.Write(salt, 0, salt.Length); CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write); // 新增:清理time字符串的非法字符 string cleanTime = Regex.Replace(time, @"[\p{C}]", string.Empty); foreach (char invalidChar in Path.GetInvalidPathChars()) { cleanTime = cleanTime.Replace(invalidChar.ToString(), string.Empty); } // 改用Path.Combine拼接路径 string pathSave = Path.Combine(Path.GetTempPath(), $"disk{cleanTime}.vhd"); MessageBox.Show(pathSave); FileStream fsIn = new FileStream(pathSave, FileMode.Open); byte[] buffer = new byte[1048576]; int read; try { while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) { Application.DoEvents(); cs.Write(buffer, 0, read); } fsIn.Close(); } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message, "Unmount Encryption - Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { cs.Close(); fsCrypt.Close(); } }
内容的提问来源于stack exchange,提问作者Tomás
相关产品推荐
相关产品推荐

