Unity中的文件读写TXT 与XML
在游戏开发中,有的单机游戏会用到保存数据到本地,或者根据本地的数据来进行下次的设置。这里,鄙人介绍TXT与xml 的读写。
首先是txt:
新建一个unity工程,创建一个cube,新建一个脚本:CreatTxt挂载到cube上。然后打开脚本。输入一下的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System .IO ;//引入文件流操作命名空间
public class CreatTxt : MonoBehaviour {// Use this for initializationvoid Start () {CreateFile ("D:/MyTxt.txt","这是你写的信息");CreateFile ("D:/MyTxt.txt","Hello!I am Jtro!");}//End of Start /// <summary>/// Creates the file.创建文本的方法/// </summary>/// <param name="_filePath">File path. 文件的路径</param>/// <param name="_data">Data. 文件的内容</param>public void CreateFile (string _filePath ,string _data){StreamWriter sw;FileInfo fi = new FileInfo (_filePath);//如果文件不存在if (!fi.Exists) {//创建文件sw = fi.CreateText ();}else{//打开文件sw = fi .AppendText ();}sw.WriteLine (_data);//以行的形式写入sw .Write (_data);//首位衔接的方式写入sw .Close ();//关闭流sw .Dispose ();//销毁流}/// <summary>/// Destroies the file.销毁创建的文本/// </summary>/// <param name="_filePath">File path. 文本的路径</param>public void DestroyFile (string _filePath){if(File .Exists (_filePath)){File.Delete (_filePath);Debug.Log ("删除文件: "+_filePath);}}
然后保存运行:
运行后的截图
下面是文件的读取:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System .IO ;//引入文件流操作命名空间
public class CreatTxt : MonoBehaviour {List <string>listxt = new List<string> ();void Awake (){CreateFile ("D:/MyTxt.txt","这是你写的信息");CreateFile ("D:/MyTxt.txt","Hello!I am Jtro!");}// Use this for initializationvoid Start () {StartCoroutine (WWWLoadFile (_filePath:"file:///D:/MyTxt.txt"));listxt = LoadFile (_filePath:"D:/MyTxt.txt");foreach (var item in listxt) {Debug.Log (item );}DestroyFile (_filePath:"D:/MyTxt.txt" );}//End of Start /// <summary>/// Creates the file.创建文本的方法/// </summary>/// <param name="_filePath">File path. 文件的路径</param>/// <param name="_data">Data. 文件的内容</param>public void CreateFile (string _filePath ,string _data){StreamWriter sw;FileInfo fi = new FileInfo (_filePath);//如果文件不存在if (!fi.Exists) {//创建文件sw = fi.CreateText ();}else{//打开文件sw = fi .AppendText ();}sw.WriteLine (_data);//以行的形式写入//sw .Write (_data);//首位衔接的方式写入sw .Close ();//关闭流sw .Dispose ();//销毁流}/// <summary>/// Destroies the file.销毁创建的文本/// </summary>/// <param name="_filePath">File path. 文本的路径</param>public void DestroyFile (string _filePath){if(File .Exists (_filePath)){File.Delete (_filePath);Debug.Log ("删除文件: "+_filePath);}}/// <summary>/// Loads the file.文件流读取文件信息/// </summary>/// <returns>The file. 文件路径</returns>/// <param name="_filePath">File path.</param>public List <string>LoadFile (string _filePath){List<string > str = new List<string> ();//实例化//如果文件不存在,返回空if (!File .Exists (_filePath)){Debug.Log ("文件未找到: " + _filePath);return null;}StreamReader sr;sr = File.OpenText (_filePath);string strLine = "";//如果第一行的内容不为空while ((strLine= sr.ReadLine ())!=null){str.Add (strLine);//将每一行的内容存入链表中}sr.Close ();sr.Dispose ();return str;}/// <summary>/// WWWs the load file.WWW的方式读取文件/// </summary>/// <returns>The load file.</returns>/// <param name="_filePath">File path. 文件的地址</param>public IEnumerator WWWLoadFile (string _filePath){//如果是本地路径,路径前加“file:///”WWW www = new WWW (_filePath);//实例化Debug .Log (_filePath);yield return www;if (www.error == null) {Debug.Log (www.text+"WWW");} else {Debug.Log ("文本读取错误: "+www .error);}}
}
QQ浏览器截屏未命名.png
OK,TXT的先介绍到这
下面是xml的使用方法,一样的,新建工程,新建cube,新建一个脚本:XmlData,不继承MonoBehavior。写下如下代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System .Xml .Serialization ;//命名空间,序列化用
/// <summary>
/// Xml data.XML的数据类
/// </summary>
//[XmlRoot ("MyRoot")] //更改节点名称
public class XmlData {//[XmlElement ("玩家名称")] // 更改子节点名称public string playName;//[XmlElement ("等级")]public int level;//[XmlIgnore] //忽略public int gold;public XmlData() //构造函数{playName = "Jtro01";level = 1;gold = 100;}}
这里的不能改节点名称,不知为何。等我找到原因再修改。
然后新建一个脚本:SerializerXml,编写如下代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System .Xml .Serialization ;//引入命名空间,负责把对象序列化到xml,并从xml中反序列化
using System ;
using System .IO ;
public class SerializerXml : MonoBehaviour {static SerializerXml instance;/// <summary>/// Start this instance.单例/// </summary>public static SerializerXml Instance{get {if (instance == null){GameObject singleton = new GameObject ();singleton .name = "SerializerXmlManager";instance = singleton.AddComponent <SerializerXml > ();}return instance;}}//定义一个委托public delegate void WWWLoadFromXmlEventHandler (object obj);//WWW加载XML完成事件public event WWWLoadFromXmlEventHandler onWWWLoadFormXmlOver;/// <summary>/// Saves to xml.保存xml/// </summary>/// <param name="filePath">File path.文件的路径</param>/// <param name="sourceObj">Source object.源对象</param>/// <param name="Type">Type.类型 </param>/// <param name="xmlRootName">Xml root name.根节点的名字</param>public void SaveToXml (string filePath ,object sourceObj, Type type = null ,string xmlRootName = null){if(!string .IsNullOrEmpty (filePath )&&sourceObj != null){type = type != null ? type : sourceObj.GetType ();//三元表达式//三元表达式等同于:
// if (type != null) {
// type = type;
// } else {
// type = sourceObj.GetType ();
// }using (StreamWriter writer = new StreamWriter (filePath)){XmlSerializer xmlSerializer = string.IsNullOrEmpty (xmlRootName) ? new XmlSerializer (type) : new XmlSerializer (type, new XmlRootAttribute (xmlRootName));xmlSerializer.Serialize (writer, sourceObj);Debug.Log ("保存成功!");}}}/// <summary>/// Loads the form xml.加载xml/// </summary>/// <returns>The form xml. </returns>/// <param name="filePath">File path.xml路径 </param>/// <param name="type">Type. 反序列化类型</param>public object LoadFormXml (string filePath,Type type){object result = null;if (File .Exists (filePath)){using (StreamReader reader = new StreamReader (filePath)){XmlSerializer xmlSerializer = new XmlSerializer (type);result = xmlSerializer.Deserialize (reader);}}return result;}/// <summary>/// WWWs the load for xml.WWW的方式加载XML/// </summary>/// <param name="_firlUrl">Firl URL. xml的地址</param>/// <param name="type">Type.反序列化的类型</param>public void WWWLoadForXml(string _firlUrl,Type type){StartCoroutine (WWW_LoadForXml (_firlUrl ,type));}/// <summary>/// WWW load for xml.WWW的方式加载XML/// </summary>/// <returns>The w load for xml.</returns>/// <param name="_fileUrl">File URL.</param>/// <param name="type">Type.</param>IEnumerator WWW_LoadForXml(string _fileUrl ,Type type){object obj = null;WWW www = new WWW (_fileUrl);yield return www;if (www.error == null) {XmlSerializer xmlSerializer = new XmlSerializer (type);byte[] b = System.Text.Encoding.UTF8.GetBytes (www.text);MemoryStream ms = new MemoryStream (b);obj = xmlSerializer.Deserialize (ms);ms.Close ();}else{}//将加载完成的xml对象发送到监听对象上if(onWWWLoadFormXmlOver !=null){onWWWLoadFormXmlOver (obj);}}// Use this for initialization//序列化XML保存实例void Start () {
// XmlData xmlData = new XmlData ();
// xmlData .playName = "Jtro02";
// xmlData.level = 2;
// xmlData .gold = 200;
// //最关键的一步:序列化生成XML
// SerializerXml .Instance .SaveToXml ("D:/myXml.xml",xmlData);//反序列读取实例,start里面的方法运行后注释,D盘就有了xml文件了。然后反序列化读取//非WWW加载
// XmlData xmlData = SerializerXml .Instance .LoadFormXml ("D:/myXml.xml",typeof (XmlData))as XmlData;
// Debug.Log ("name: "+xmlData .playName +"Level: "+xmlData .level+"gold: "+xmlData .gold);//WWW的加载方式,监听WWW加载完毕事件SerializerXml .Instance .onWWWLoadFormXmlOver +=onWWWLoadXmlOver;SerializerXml.Instance.WWWLoadForXml ("file:///D:/myXml.xml", typeof(XmlData));}//End of Start void onWWWLoadXmlOver (object obj){XmlData xmlData = obj as XmlData;Debug.Log ("...name:" + xmlData.playName + " level:" + xmlData.level + " gold:" + xmlData.gold);//取消监听SerializerXml .Instance .onWWWLoadFormXmlOver -=onWWWLoadXmlOver;}
}
然后运行,运行的时候先把start方法中的这一部分:
// XmlData xmlData = new XmlData ();// xmlData .playName = "Jtro02";// xmlData.level = 2;// xmlData .gold = 200;// //最关键的一步:序列化生成XML// SerializerXml .Instance .SaveToXml ("D:/myXml.xml",xmlData);
的注释删除掉,也就是让这部分代码起作用。
运行一次,再注释。然后可以用下面的方法读取了。