C#读取远程CNC机器IPC文件提示被占用的解决方法
解决远程CNC文件读取被占用的问题
问题核心在于File.ReadAllLines默认会以独占访问模式打开文件,而CNC机器写入该文件时可能未允许共享读取,导致代码报错。手动打开文件(如记事本、资源管理器)之所以正常,是因为这些工具默认使用允许共享的文件访问模式。
修改后的代码
public void Read_Alarm_Log_File() { string networkPath = "\\\\" + TagService.IP_Win_List + "\\F$"; string filePath = Path.Combine(networkPath, "mmc2", "proto.txt"); NetworkCredential credentials = new NetworkCredential("username", "XXXXX"); TagService.Alarm_log_File_content.Clear(); try { using (new NetworkConnection(networkPath, credentials)) { // 以允许共享读写的模式打开文件,避免独占冲突 using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var streamReader = new StreamReader(fileStream)) { string line; while ((line = streamReader.ReadLine()) != null) { TagService.Alarm_log_File_content.Add(line + "\n"); } } } } catch (Exception ex) { using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine($"Alarm Log File could not be read: {ex} {DateTime.Now}"); } } }
关键改动说明
- 用
FileStream手动指定文件访问参数:FileShare.ReadWrite允许其他进程同时读取或写入该文件,避免独占锁冲突。 - 使用
StreamReader逐行读取,和原代码逻辑一致,但更灵活控制文件打开模式。 - 用
Path.Combine拼接路径,避免手动拼接字符串可能出现的格式错误。
额外建议
如果偶尔还是出现读取失败,可以添加重试机制,因为CNC写入文件的时间很短,重试大概率能成功:
public void Read_Alarm_Log_File() { string networkPath = "\\\\" + TagService.IP_Win_List + "\\F$"; string filePath = Path.Combine(networkPath, "mmc2", "proto.txt"); NetworkCredential credentials = new NetworkCredential("username", "XXXXX"); TagService.Alarm_log_File_content.Clear(); int retryCount = 3; try { using (new NetworkConnection(networkPath, credentials)) { while (retryCount > 0) { try { using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var streamReader = new StreamReader(fileStream)) { string line; while ((line = streamReader.ReadLine()) != null) { TagService.Alarm_log_File_content.Add(line + "\n"); } } break; // 读取成功,跳出重试循环 } catch (IOException) when (retryCount > 1) { retryCount--; Thread.Sleep(1000); // 等待1秒后重试 } } } } catch (Exception ex) { using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine($"Alarm Log File could not be read: {ex} {DateTime.Now}"); } } }
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

