如何解析包含序列化的PHP的CSV文件
发布网友
发布时间:2022-04-20 16:09
我来回答
共1个回答
热心网友
时间:2022-04-06 05:15
在Unity3D中可以使用使用继承自scriptObject类并添加CreateAssetMenu属性方便实现类的序列化,但值得注意的是这种方式并不支持程序打包之后数据的保存。
当然常用的还有xml和json的方式来保存类的信息,在需要的时候加载出来,这方面就不多说了。但是直观的来说,表最适合一些简单的数据类型的记录,键值对最简单。
特别是一个一些程序的配制或者标题对应于一段富文本来说,这样的信息最适合保存在csv文件中。
状态模式:(例1)
面对象常的设计模式中,状态模式比较常用的一种。一个类的某个属性有多种状态,而这个类实现通用的方法,在不同的状态下会产生不同的后果,不同的状态分别抽象为一个个独立的类,其内部可以触发整体状态的改变。只需要考虑到不同状态下具体的实现和状态的转换,而大大简化了用户调用的接口。
CSV文件:(例2)
利用excel,可以进行csv文件的编辑,可以方便的将只包含文字信息的表格导出为csv文件,并且可以进行重复编辑。
程序中要使用csv,先要将其文本文件的格式进行透彻分析。
测试一、 先建立一个简单的表格如图所示(没有引号):
然后利用notepad打开可以看到下面这样的格式:
id,name,sex
这种情况下,要解析实在是太容易了,要什么设计模式...
测试二、填写一些复杂的数据试试(有引号):
notepad打开:
id,name,sex
1,小名:"小艺",girl
这种情况下,貌似也不太复杂,只要用“,”分解不就好了?
测试三、更为复杂的信息:
notepad打开试试:
id,name,sex
1,"小名:""小艺"",大名:""杨彬艺""",girl
这下坏了,直接用,分解是不可能的,特别是对于更为复杂的一大段文字信息。
测试四、段内还有换行呢!
notepad内信息如下:
id,name,sex
1,"小名:""小艺""
大名:""杨彬艺""",girl
真的换行了哦,原来以为可以readline就可以读取出一组数据的方式也行不通了...
程序接口设计:
要将程序设计为通用易用,不得不遵循接口隔离的原则,尽量简化类的接口。要实现程序的面对象特性,还要将每个类的功能设计得相对单一,以降低类之前的偶合。
首先设计的最,最外层CsvLoaderManager,这应该是一个单例,方便全局使用并且能使用一些MonoBehaiver的方法,其主要的功能就是加载和保存csv文件。
其次要设计的,ParserCSV,其主要的功能是将csv文本信息转换为一个二维数组。
然后设计的是一个状态机ParserStateMachine,读取遇到的一个字符信息。
public class ParserStateMachine
{
public LineStartState LineStartState;
public ValueStartState ValueStartState;
public ValueState ValueState;
public QuotedValueState QuotedValueState;public QuoteState QuoteState;
private ParserState currState;
public ParserContext context;
public const char CommaCharacter = ',';
public const char QuoteCharacter = '"';
public bool TrimTrailingEmptyLines;
public int MaxColumnsToRead;
public ParserStateMachine(bool TrimTrailingEmptyLines = false,int MaxColumnsToRead = 0){
this.TrimTrailingEmptyLines = TrimTrailingEmptyLines;this.MaxColumnsToRead = MaxColumnsToRead;context = new global::ParserContext();
LineStartState = new LineStartState(this);ValueStartState = new ValueStartState(this);ValueState = new ValueState(this);
QuotedValueState = new QuotedValueState(this);QuoteState = new QuoteState(this);
}
public void SetState(ParserState currState){
this.currState = currState;
}
public void AnyChar(char ch)
{
currState.AnyChar(ch);
}
public void Comma()
{
currState.Comma();
}
public void EndOfLine()
{
currState.EndOfLine();
}
public void Quote()
{
currState.Quote();
}
}
然后是抽象的状态类ParserState,和具体的LineStartState,ValueStartState,ValueState,QuotedValueState,QuoteState 这五种状态(分别是换行状态、值开始状态、值状态、引号内值状态、引号状态);最后是将二得到的二维数据转换为具体的类的,因为每个类者有相似的转换方法,可以写一个模板类,用编辑器扩展生成一个具体的类并继承于一个抽象的CSVTable。
以上的状态模式只适用于数据加载到具体类中,要实现一个将数据转换为csv信息的方式,并不是简单的反过来写就行。
具体实现参见github上的源码吧
https://github.com/zouhunter/CSVConfig
注意事项:
1、 csv文件利用excel打开之后格式会发生变化,程序中使用时,需要提前将格式转换为UTF_8.