(StreamReader.ReadLine()==null)还是(-1 != StreamReader.Peek())?

本文介绍三种从文本文件中删除以特定字符结尾的行的方法。通过逐行读取和条件判断实现,探讨不同读取方式的优缺点。

有人问到一个问题:

一个文本里有多行,如:
geafd1
bragd2
beree3
beaee4
dfefa/
fdasf5
feafd/
..
..
怎么把结尾是“/”的行删掉?

 

其实,解决思路很简单,将文本逐行读取到数组中,再遍历数组判断即可。于是,某个项目中常用方法:

方法一:

 

这也是微软提供的示例,在实际使用中发现,有时候,该方法的缺陷在于不能读取完整地读取文件所有行。怀疑是缓冲区过小。查MSDN说明:

StringReader      . ReadLine 方法将行定义为后面跟有下列符号的字符序列:换行符(“/n”)、回车符(“/r”)或后跟换行符的回车符(“/r/n”)。 所产生的字符串不包含终止回车符和/或换行符。 如果已到达基础字符串的结尾,则返回值为 null    
http://msdn.microsoft.com/zh-cn/library/system.io.streamreader.readline.aspx

我的理解:如果由于编码的问题,导致读取异常,也就是无法读取行标志时,可能会认为已到文件结尾而中断下行的读取。这也解释了为什么会有时读取不完整的原因。


 

如何避免这个问题呢?可以使用方法二:

方法二:

 

这里使用 StreamReader的Peek()方法,依据MSDN的说明,

Peek 方法返回一个整数值以便确定是否到达文件末尾,或发生其他错误。 这样一来,用户在将返回值强制转换为 Char 类型之前就可以首先检查该值是否为 -1。

换句话说,它不需要先转换字符,即可返回是否达到文件末尾。

http://msdn.microsoft.com/zh-cn/library/system.io.streamreader.peek.aspx

 

其实还可以用第三种方法: File       ReadAllLines 方法 (String)

方法三:


MSDN说明:

此方法打开一个文件,读取文件的每一行,然后将每一行添加为字符串数组的一个元素。 然后它关闭文件。 根据定义,一行就是一个后面跟有下列符号的字符序列:回车符(“/r”)、换行符(“/n”)或回车符后紧跟一个换行符。 所产生的字符串不包含终止回车符和/或换行符。

此方法尝试根据现存的字节顺序标记来自动检测文件的编码。 可检测到编码格式 UTF-8 和 UTF-32(包括 big-endian 和 little-endian)。

 

http://msdn.microsoft.com/zh-cn/library/s2tte0y1.aspx

方法三也可能存在与方法一类似的缺陷。

 

邀月注:本文版权由邀月和CSDN共同所有,转载请注明出处。
助人等于自助!   3w@live.cn
   

         

using Newtonsoft.Json; using Serilog; using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Text; using System.Threading.Tasks.Dataflow; namespace BeiDou { internal class Program { private static TcpListener tcpListener; private static byte[] tcp_buffer = new byte[8192]; private static Queue<char> char_buffer = new Queue<char>(); private static double fixed_location = 0; private static double fixed_alpha = 0; private static double fixed_beta = 0; private static int gps_status = 0; private static DateTime gps_time = DateTime.MinValue; private static string configfile = "config.json"; private static ConfigData configData = new ConfigData(); private static MqttClient _client = null; private static TcpClient _tcpClient = null; private static PlcConnector plcConnector; private static ApiService apiService; public static ConfigData LoadConfig(string filePath) { try { if (File.Exists(filePath)) { string jsonString = File.ReadAllText(filePath); ConfigData data = JsonConvert.DeserializeObject<ConfigData>(jsonString); return data; } else { return null; } } catch (Exception ex) { return null; } } private static void StartListener() { try { int port = configData.port; tcpListener = new TcpListener(IPAddress.Any, port); tcpListener.Start(); tcpListener.BeginAcceptTcpClient(AcceptCallback, tcpListener); Log.Information($"tcp服务启动@Port {port}"); } catch (Exception ex) { Log.Information($"服务器启动失败: {ex.Message}"); } } private static void AcceptCallback(IAsyncResult ar) { var r = tcpListener.EndAcceptTcpClient(ar); Log.Information($"tcp 客户端连接来自:{r.Client?.RemoteEndPoint?.ToString()}"); if (_tcpClient != null) { try { _tcpClient.Close(); lock (char_buffer) { char_buffer.Clear(); } } catch (Exception e) { } Log.Information($"断开前一个连接:{_tcpClient.Client?.RemoteEndPoint?.ToString()}"); } _tcpClient = r; _tcpClient.GetStream().BeginRead(tcp_buffer, 0, tcp_buffer.Length, ReadCallback, _tcpClient); Log.Information($"开始读入数据"); tcpListener.BeginAcceptTcpClient(AcceptCallback, tcpListener); } private static void ReadCallback(IAsyncResult ar) { try { int bytesRead = _tcpClient.GetStream().EndRead(ar); if (bytesRead == 0) { Log.Information($"客户端断开"); _tcpClient.Close(); return; } string data = Encoding.ASCII.GetString(tcp_buffer, 0, bytesRead); lock (char_buffer) { foreach (char c in data) { char_buffer.Enqueue(c); } } _tcpClient.GetStream().BeginRead(tcp_buffer, 0, tcp_buffer.Length, ReadCallback, _tcpClient); gps_time = DateTime.Now; } catch (Exception ex) { Log.Information($"客户端连接出错: {ex.Message}"); //_tcpClient.GetStream().Close(); // 明确关闭流 //_tcpClient.Close(); // 明确关闭客户端 } } private static void ProcessBufferAsync() { StringBuilder sb = new StringBuilder(); string psatMessage = null; string gpggaMessage = null; while (true) { lock (char_buffer) { while (char_buffer.Count > 0 && char_buffer.Peek() != '$') { char_buffer.Dequeue(); } while (char_buffer.Count > 0 && char_buffer.Peek() != '\n') { sb.Append(char_buffer.Dequeue()); } if (char_buffer.Count > 0 && char_buffer.Peek() == '\n') { char_buffer.Dequeue(); string message = sb.ToString(); sb.Clear(); if (message.StartsWith("$PSAT")) { psatMessage = message; } else if (message.StartsWith("$GPGGA")) { gpggaMessage = message; } if (psatMessage != null && gpggaMessage != null) { Process(psatMessage, gpggaMessage); psatMessage = null; gpggaMessage = null; } } } Thread.Sleep(50); } } private static void Process(string PSAT, string GPGGA) { string[] parts1 = PSAT.Split(','); var hpr_heading = MakeContinuous(float.Parse(parts1[3])); var hpr_pitch = float.Parse(parts1[4]); var hpr_roll = float.Parse(parts1[5].Split('*')[0]); string[] parts2 = GPGGA.Split(','); double lat = double.Parse(parts2[2].Substring(0, 2)) + double.Parse(parts2[2].Substring(2)) / 60; double lon = double.Parse(parts2[4].Substring(0, 3)) + double.Parse(parts2[4].Substring(3)) / 60; double alt = double.Parse(parts2[9]); if (parts2[3] == "S") lat = -lat; if (parts2[5] == "W") lon = -lon; double east, north; WGS84ToUTM(lat, lon, out east, out north); var latitude = lat; var longitude = lon; var altitude = double.Parse(parts2[9]); var easting = east; var northing = north; var solution_status = parts2[6]; gps_status = Convert.ToInt32(solution_status); var result = GetLocation(hpr_heading, hpr_pitch, easting, northing, altitude); var locate = result.Item1; var alpha = 270 - (hpr_heading + 180) % 360 + configData.alpha_fix; var beta = -hpr_pitch + configData.beta_fix; var location = locate + configData.dx + configData.location_fix; //临时 var location_fix = location + alpha * 0.017 + 2.2; var alpha2 = alpha * -1 + 90; fixed_location = location_fix; fixed_alpha = alpha2; fixed_beta = beta; } private static double MakeContinuous(double angle, double reference = 180) { if (angle < reference) angle += 360; return angle - reference; } private static void WGS84ToUTM(double lat, double lon, out double easting, out double northing) { const double a = 6378137.0; const double e = 0.081819190842; const double k0 = 0.9996; const int zone = 51; double latRad = lat * Math.PI / 180.0; double lonRad = lon * Math.PI / 180.0; double lonOrigin = (zone - 1) * 6 - 180 + 3; double lonOriginRad = lonOrigin * Math.PI / 180.0; double N = a / Math.Sqrt(1 - e * e * Math.Sin(latRad) * Math.Sin(latRad)); double T = Math.Tan(latRad) * Math.Tan(latRad); double C = e * e * Math.Cos(latRad) * Math.Cos(latRad) / (1 - e * e); double A = (lonRad - lonOriginRad) * Math.Cos(latRad); double M = a * ((1 - e * e / 4 - 3 * e * e * e * e / 64 - 5 * e * e * e * e * e * e / 256) * latRad - (3 * e * e / 8 + 3 * e * e * e * e / 32 + 45 * e * e * e * e * e * e / 1024) * Math.Sin(2 * latRad) + (15 * e * e * e * e / 256 + 45 * e * e * e * e * e * e / 1024) * Math.Sin(4 * latRad) - (35 * e * e * e * e * e * e / 3072) * Math.Sin(6 * latRad)); easting = k0 * N * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * e * e) * A * A * A * A * A / 120) + 500000.0; northing = k0 * (M + N * Math.Tan(latRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * e * e) * A * A * A * A * A * A / 720)); if (lat < 0) northing += 10000000.0; // ϰ } private static (double, double, double) GetLocation(double heading, double pitch, double e, double n, double alt) { //var dx = -0.019701; //var dl = 0.070986; //var dp = -0.065288; //var dh = -1.826911; //var dn = 1037737.1908643508; //var w_z = -1.9326628753411224; //var dx = -0.158508; //var dl = 0.978683; //var dp = -0.059042; //var dh = -1.824058; //var dn = 1033585.1515670037; //var w_z = -1.931425470920315; double heading_r = MakeContinuous(heading) * Math.PI / 180.0; double pitch_r = pitch * Math.PI / 180.0; //var dx = configData.dx; //var dl = configData.dl; //var dp = configData.dp; //var dh = configData.dh; var dn = configData.dn; var de = configData.de; var w_z = configData.w_z; var X = dn + n * Math.Cos(w_z) - e * Math.Sin(w_z); //var location = X + dx - (4.3 + (12.7 + dl) * Math.Cos(pitch_r + dp) * Math.Cos(heading_r + dh)); var dx = -1.73158823; var dbeta = -0.23008302; var dalpha = -2.0795134; var dl2 = 0.39443275; var beta = pitch_r + dbeta; var alpha = heading_r + dalpha; var l1 = 4.300; var l2 = 20.00 + dl2; var lt = l1 + l2 * Math.Cos(beta); var d = 3.7; var distance = lt * Math.Cos(alpha) - d * Math.Sin(alpha); var location = X + dx - distance; return (location, 0, 0); } static void Main(string[] args) { Serilog.Log.Logger = new Serilog.LoggerConfiguration() .MinimumLevel.Information() .WriteTo.File("log-.txt", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] [{SourceContext}] {Message}{NewLine}{Exception}" ) .WriteTo.Console() .CreateLogger(); Log.Information("==========程序启动=========="); configData = LoadConfig(configfile); if (configData == null) { configData = new ConfigData(); } StartListener(); Task.Run(() => { while (true) { ProcessBufferAsync(); } }); _client = new MqttClient(DateTime.Now.Ticks.ToString(), "127.0.0.1", 1883); _client.Init(); apiService = new ApiService(); plcConnector = new PlcConnector(); Task.Run(() => { while (true) { var _sec = (DateTime.Now - gps_time).TotalSeconds; if (_sec < 2) { if (gps_status == 4) { try { SLState state = apiService.GetEquipmentStateAsync().Result; var str = JsonConvert.SerializeObject(new { WalkPosition = fixed_location, RotatePosition = fixed_alpha, PitchPosition = fixed_beta, ShenSuo = Math.Round(state.boomExtensionPosition, 2), FuYang = state.pitchPosition, ZouXing = state.walkPosition, time = DateTime.Now }); _client.Publish($"{configData.mqtt_topic}/BD", str); plcConnector.WriteThreeFloats((float)fixed_location, (float)fixed_alpha, (float)fixed_beta); Log.Information($"{fixed_location:0.00},{fixed_alpha:0.00},{fixed_beta:0.00},{gps_time.Millisecond},{gps_status}"); } catch (Exception ex) { Log.Warning($"错误: {ex.Message}"); } } else { Log.Warning($"差分失败:{gps_status}, {_sec}"); } } else { Log.Warning($"离线:{gps_status}, {_sec}"); if (_sec > 5 && gps_time != DateTime.MinValue) { try { _tcpClient.Close(); } catch (Exception e) { Log.Information($"断开失败3:{gps_status}, {_sec}"); } } } Thread.Sleep(500); } } ); while (true) { Console.ReadLine(); } } } }
最新发布
09-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值