撸码是需要直觉的

随着撸码的时间增加,码感也会加强,今天看一个编码直觉案例吧!

案例:

需求:把查询到的数据列表生成csv文件

nuget包:CsvHelper

数据实体类:

    /// <summary>/// 商品/// </summary>public class Goods{/// <summary>/// 编号/// </summary>public uint ID{ get; set; }/// <summary>/// 名称/// </summary>public string Name{ get; set; }/// <summary>/// 规格/// </summary>public string Spec{ get; set; }/// <summary>/// 单位/// </summary>public string Unit{ get; set; }/// <summary>/// 制造商/// </summary>public string Manufacturer{ get; set; }/// <summary>/// 价格/// </summary>public decimal Price{ get; set; }/// <summary>/// 这里是为了打印数据方例重写ToString()/// </summary>public override string ToString(){return $"ID={ID},Name={Name},Unit={Unit},Spec={Spec},Price={Price},Manufacturer={Manufacturer}";}}

定义了一个csv操作的接口:

public interface ICsvHandle
{List<Goods> ReadCsv(string file);void WriteCsv(string file, List<Goods> goodses);
}

为了演示方便,Demo中的数据列表是通过Bogus产生(bogus在之前的文章中介绍过)

   static List<Goods> GoodsCreater(){var goodses = new List<Goods>();var options = new JsonSerializerOptions();options.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All);for (var i = 0; i < 100; i++){var goodsFaker = new Faker<Goods>("zh_CN").RuleFor(x => x.ID, x => x.Random.UInt()).RuleFor(x => x.Name, x => x.Random.ArrayElement(new string[]{"甲销唑注射液",
"葡萄糖注射液",
"盐水(氯化钠)",
"利巴韦林病毒唑针",
"氟康唑氯化钠注射液(康锐)",
"安痛定针",
"维生素B12针",
"硫酸阿米卡星注射液",
"氯化钠注射液(塑料瓶)",
"转移因子注射液",
"血塞通粉针",
"苦碟子注射液",
"注射用培美曲塞二钠(爱立汀)",
"左克注射液",
"维生素C注射液",
"硫酸庆大霉素注射液",
"盐酸左氧氟沙星注射液",
"蔗糖铁注射液",
"注射用青霉素钠",
"维生素B1针",
"疏血通注射液",
"胃复安盐酸甲氧氯普胺注射液",
"硫酸庆大霉素注射液",
"葡萄糖注射液50%",
"银杏达莫注射液",
"硫酸庆大霉素注射液",
"5%葡萄糖注射液",
"注射用氨曲南",})).RuleFor(x => x.Price, x => x.Random.Decimal()).RuleFor(x => x.Unit, x => x.Random.ArrayElement(new string[] { "个", "片", "瓶", "盒", "支", "克" })).RuleFor(x => x.Spec, x => x.Random.ArrayElement(new string[]{"5*20ml",
"250ml",
"1ml*10支",
"100ml:0.2g",
"2毫升*10支",
"10支",
"2ml*10.2克*10支",
"100ml",
"3毫升:2毫升*10支",
"20毫克",
"10mg*10支",
"0.5克",
"2ml:0.1g",
"0.25G*2ML",
"4万单位*10支",
"100ml*0.1g",
"1g",
"80万单位",
"2ml*10支",
"5毫克*60片",
"1ml:10mg",
"4万*2ml*10支",
"20ML*5支",
"5ml",
"2ml:40mg(4万单位)",
"250ml",
"0.5克*10支",
"5ML;17.5MG",
"2ML:0.5G*10支",})).RuleFor(x => x.Manufacturer, x => x.Random.ArrayElement(new string[]{"山东齐都药业/山西云鹏",
"侯马霸王药业/山西晋新双鹤/天津新郑/西安/贵州",
"山西临汾云鹏药业、山东齐都药业/山西银湖/石家庄四药/河南科伦",
"安徽联谊/无锡",
"扬子江药业集团",
"新乡常乐制药/山西太原药业/天津焦作/郑州",
"天津药业焦作",
"山东方明药业集团股份有限公司",
"石家庄四药有限公司",
"湖南一格制药有限公司",
"哈尔滨",
"通化华夏制药有限责任公司",
"德州德药制药有限公司",
"扬子江药业",
"山西晋新双鹤药业/新乡市新辉药业/河南润弘",
"河南辅仁怀庆堂制药/濮阳市汇元药业/新乡常乐",
"广西裕源药业、四川科伦大药厂",
"成都天台山制药有限公司",
"华北制药",
"安阳九州药业、山东方明药业/石药银湖制药",
"牡丹江友博药业有限公司",
"濮阳汇元/天津药业集团新郑",
"天津药业焦作/侯马",
"湖南科伦/焦作民康",
"贵州益佰制药股份有限公司",
"新乡市新辉药业/新乡常乐制药/濮阳市汇元药业",
"山东华鲁制药/山东齐都/山西云鹏制药/西安汉丰",
"重庆圣华曦药业",}));goodses.Add(goodsFaker.Generate());}return goodses;}

第一版:

csv文件格式是utf8

public class BasisCsvHandle : ICsvHandle
{public List<Goods> ReadCsv(string file){var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var reader = new StreamReader(file))using (var csv = new CsvReader(reader, config)){var goodses = csv.GetRecords<Goods>();return goodses.ToList();}}public void WriteCsv(string file, List<Goods> goodses){var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var writer = new StreamWriter(file)){using (var csv = new CsvWriter(writer, config)){csv.WriteRecords(goodses);}}}
}

后来有的客户要BOM类型的UTF8,其实就是在文件开头加上byte[] BOM = { 0xEF, 0xBB, 0xBF };这个字节数组就ok

为了适配合有无BOM和非BOM的UTF8,对接口进行了重构,增加默认属性(正好练一下接口默认属性的用法),这种做法的好处是不打扰BasisCsvHandle的代码,当然,也可以更深层的重构ICsvHandle中的两个方法来适配是否是BOM UTF8

public interface ICsvHandle
{List<Goods> ReadCsv(string file);void WriteCsv(string file, List<Goods> goodses);private static bool _isBOM;public bool IsBOM { get => _isBOM; set => _isBOM = value; }
}

第二版:

public class StrengthenCsvHandle : ICsvHandle
{public List<Goods> ReadCsv(string file){MemoryStream memory = null;using (var reader = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite)){var bytes = new byte[reader.Length];reader.Read(bytes, 0, bytes.Length);if (((ICsvHandle)this).IsBOM){bytes = bytes.Skip(3).Take(bytes.Length - 3).ToArray();}memory = new MemoryStream(bytes);}var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var reader = new StreamReader(memory))using (var csv = new CsvReader(reader, config)){var goodses = csv.GetRecords<Goods>();return goodses.ToList();}}public void WriteCsv(string file, List<Goods> goodses){var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var writer = new StreamWriter(file)){using (var csv = new CsvWriter(writer, config)){csv.WriteRecords(goodses);}}if (((ICsvHandle)this).IsBOM){//追究加BOMusing (var writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite)){var bytes = new byte[writer.Length];writer.Read(bytes, 0, bytes.Length);byte[] BOM = { 0xEF, 0xBB, 0xBF };var list = new List<byte>();list.AddRange(BOM);list.AddRange(bytes);writer.Position = 0;writer.Write(list.ToArray(), 0, list.Count);}}}
}

虽然能实现功能,但是觉得这样的代码太啰嗦,这里的本质就是在写数据时加上三个字节,读取数据时,少读三个字节直觉告诉我,应该好像也许或者能有更简单的方式。

第三版:

public class PerfectCsvHandle : ICsvHandle
{public List<Goods> ReadCsv(string file){var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var reader = new StreamReader(file))using (var csv = new CsvReader(reader, config)){if (((ICsvHandle)this).IsBOM){reader.BaseStream.Position = 3;}var goodses = csv.GetRecords<Goods>();return goodses.ToList();}}public void WriteCsv(string file, List<Goods> goodses){var config = new CsvConfiguration(CultureInfo.InvariantCulture){NewLine = "\r\n"};using (var writer = new StreamWriter(file)){using (var csv = new CsvWriter(writer, config)){if (((ICsvHandle)this).IsBOM){byte[] BOM = { 0xEF, 0xBB, 0xBF };writer.Write(System.Text.Encoding.UTF8.GetString(BOM));}csv.WriteRecords(goodses);}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux视频教程之vsftp_B

这次主要说一下VSFTP的扩展应用 max_clients100  最大连接数max_per_ip5   每个IP最大连接数local_max_rate500000 本地用户传输的最大数anon_max_rate200000 匿名用户传输的最大数单位是字节这个就要等一会了&#xff0c;我刚才不是只设了50嘛如果是没设的话…

java collator_Java Collator compare(String, String)用法及代码示例

java.text.Collat​​or类的compare()方法用于比较两个字符串的强度&#xff0c;并根据结果返回0&#xff0c;正值和负值作为输出。用法:public abstract int compare(String source,String target)参数&#xff1a;此方法需要两个字符串之间进行比较。返回值&#xff1a;如果第…

MATLAB常用算法与应用实例分享来袭!

小天从大学开始接触数学建模&#xff0c;便开启资料收集功能。经过近几年的积累和沉淀&#xff0c;再加上对数学建模领域的深入研究&#xff0c;收集整理了丰富的数学建模资料&#xff0c;内容涵盖“MATLAB常用算法”&#xff0c;“MATLAB算法应用实例”等。截止到今天&#xf…

git的安装与使用(一)--windows平台 .

1、Create github Account &#xff08;在github网站上创建一个账号&#xff09; eg. you used the email: taitoyahoo.com 2、Download && install MsysGit (下载windows平台下的git软件) Then open the git bash , input the commends $ git config --global…

C# WPF项目实战(经典)

目的&#xff1a;输出两台摄像头图像和两路设备图像&#xff0c;每一路设备截图6张主要知识&#xff1a;1. 通过SDK调取摄像头图像&#xff0c;并对图像进行剪裁&#xff1b;2. WPF中定时器DispatcherTimer用法&#xff1b;3. WPF中跨线程访问控件方法Dispatcher.Invoke((Actio…

4个终于被破译的世界级密码

全世界有3.14 % 的人已经关注了数据与算法之美很多时候&#xff0c;一个设计精巧的密码就像数学难题一样&#xff0c;许许多多难以破解的密码让人青丝泛白&#xff0c;至今仍未见天日。不过&#xff0c;也有一些密码中的幸运儿&#xff0c;最终仍然迎来了真相大白的那天。秘密组…

NET问答: 如何在 ASP.NET Core 的 .json 文件中读取 AppSettings ?

咨询区 Oluwafemi&#xff1a;在 appsettings.json 中我有如下的 AppSettings 实体数据&#xff0c;如下代码所示&#xff1a;{"AppSettings": {"token": "1234"} }我在网上搜了很久&#xff0c;寻找如何从 .json 文件中获取 AppSettings 实体&a…

java虚拟机工作原理图_Java虚拟机工作原理

首先我想从宏观上介绍一下Java虚拟机的工作原理。从最初的我们编写的Java源文件(.java文件)是如何一步步执行的&#xff0c;如下图所示&#xff0c;首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件&#xff0c;然后JRE加载Java字节码文件&#xff0c…

如何快速测试与数据库的连接并得到连接字符串

刚做程序开发的人&#xff0c;常常为如何连接数据库&#xff0c;怎么写连接字符串而困惑。做产品安装的服务人员&#xff0c;也常常为如何快速测试本机与数据库的连接状况而头疼。这里&#xff0c;给出一个简单快速的实现方法&#xff1a;*.udl文件。 第一步&#xff1a;创建“…

奇异值的物理意义是什么?

全世界有3.14 % 的人已经关注了数据与算法之美矩阵奇异值的物理意义是什么&#xff1f;或者说&#xff0c;奇异值形象一点的意义是什么&#xff1f;把m*n矩阵看作从m维空间到n维空间的一个线性映射&#xff0c;是否&#xff1a;各奇异向量就是坐标轴&#xff0c;奇异值就是对应…

WPF使用Animation仿WeChat(微信)播放语音消息

WPF开发者QQ群&#xff1a; 340500857 前言WPF使用Animation仿WeChat&#xff08;微信&#xff09;播放语音消息&#xff1f;效果图&#xff1a;创建MyAnimationForever.cs如下&#xff1a;public class MyAnimationForever : Control{private static Storyboard MyStory;priva…

epublib java_使用Epublib处理epub文件 | 学步园

通过wlw发布在我的博客funba.cn希望csdn能重新支持wlwEpublib是一个用于处理epub文件的java类库&#xff0c;可以对epub文件进行读写处理&#xff1b;而且提供了一个阅读器&#xff0c;可以直接运行(java -jar 方式)&#xff0c;并可以打开epub类型的文件进行阅读。1、这个例子…

php注入详解

本文主要是为小菜们服务的&#xff0c;如果你已经是一只老鸟呢&#xff0c;可能某些东西会感觉比较乏味&#xff0c;但只要你仔细的看&#xff0c;你会发现很多有趣的东西哦。 阅读此文你只要明白下面的这点东西就够了。 1.明白phpmysql环境是如何搭建的&#xff0c;在光盘中…

机器学习的最佳学习路线,就在这里!

AI这个词相信大家都非常熟悉&#xff0c;近几年来人工智能圈子格外热闹&#xff0c;光是AlphoGo就让大家对它刮目相看。今天小天就来跟大家唠一唠如何进军人工智能的第一步——机器学习。在机器学习领域&#xff0c;Python已经成为了主流。一方面因为这门语言简单易上手&#x…

.NET RulesEngine(规则引擎)

一次偶然的机会&#xff0c;让我拿出RulesEngine去完成一个业务&#xff0c;对于业务来说主要是完成一个可伸缩性&#xff08;不确定的类型&#xff0c;以及不确定的条件&#xff0c;条件的变动可能是持续增加修改的&#xff09;的业务判断。比如说完成一个成就系统&#xff0c…

io流图解 java_详细讲解JAVA中的IO流

一、流的概念流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中&#xff0c;管道是一条不间断的字节流&#xff0c;用来实现程序或进程间的通信&#xff0c;或读写外围设备、外部文件等。一个流&#xff0c;必有源端和目的端&#xff0c;它们可以是计算机内存的某些区域&a…

分段函数 左右 f'正 不等于f'负 则f'导数不存在。所以不能推出f连续是否

根据单侧极限定理。当求分界处函数时。如果 f正f负 那么 f存在。 如果 f正&#xff01;f负 f不存在。 如果 f正或者f负不存在。 则f不一定不存在。单侧极限是可导的充分非必要条件。转载于:https://www.cnblogs.com/friends-wf/articles/2380690.html

Mongo规范

1.【强制】集合中的 key 禁止使用任何 "_"&#xff08;下划线&#xff09;以外的特殊字符。2.【强制】尽量将同样类型的文档存放在一个集合中&#xff0c;将不同类型的文档分散在不同的集合中&#xff1b;相同类型的文档能够大幅度提高索引利用率&#xff0c;如果文档…

java awt区域_java的awt包中有没有表示区域的类或者方法,可以传递一个Rectangle

展开全部import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.util.*;final class RectPaintDemo extends JFrame {final static private Dimension SIZE new Dimension(800, 600);public String getTitle() {return "RectPaintDemo";}pub…

BPM与Workflow的区别

ItemworkflowBPM流程管理周期设计、执行流程全周期&#xff0c;包括梳理、监控、分析目标用户群体编程人员业务人员、IT技术人员平台化设施流程引擎内核流程、组织、权限、表单、规则、门户、监控、分析等一体化的平台设施应用范围部门级&#xff0c;十余支企业级多级流程层次&…