前言:
在Unity项目中,涉及文件的读写操作,还是比较常见的。所以有必要学习一下,IO流的操作。下面以 检测 游戏中的用户昵称是否含有敏感词汇 为例,进行具体实践操作。
如图,在Unity 编辑器中生成一个 文件读写工具,用来检测词库冲突问题。
代码实现:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Data;
using UnityEditor;
public class CheckStrifeWord : EditorWindow
{
private string m_nickPath = "/Text/test.txt";
private string m_fobidPath = "/Text/words.txt";
private string[] m_nickArray = null;
private string[] m_forbidArray = null;
private string[] m_tempArray = null;
string[] m_newArray = null;
private List<string> list = new List<string>();
List<string> m_testList = new List<string>();
string str = "";
// 添加 到Tool 菜单栏 : EditorWindow
[MenuItem("Tools/Check word")]
static public void OpenBMFontMaker()
{
EditorWindow.GetWindow<CheckStrifeWord>(false, "Check Word", true).Show();
}
private void OnGUI()
{
if (GUILayout.Button("词库检测"))
{
Debug.Log("\n==== 词库检测 =====");
Init(0);
}
if (GUILayout.Button("提取 昵称词库 重复字段"))
{
Debug.Log("\n==== 提取 昵称词库 重复字段 =====");
m_newArray = new string[0];
Debug.Log("\n==== 新字符串长度 =====" + m_newArray.Length);
Init(1);
}
if (GUILayout.Button("提取 敏感词库 重复字段"))
{
Debug.Log("\n==== 提取 敏感词库 重复字段 =====");
Init(2);
}
if (GUILayout.Button("提取 昵称词库 冲突敏感词组"))
{
Debug.Log("\n==== 提取 昵称词库 冲突敏感词组 =====");
Init(3);
}
if (GUILayout.Button("删除 昵称词库 冲突敏感词组"))
{
Debug.Log("\n==== 删除 昵称词库 冲突敏感词组 =====");
Init(4);
}
}
void Init(int index = 0)
{
Debug.Log("\n====== onInIt ====== ");
// 加载用户昵称 词库文本
//TextAsset nameText = GlobalManager.LoadFromFile<TextAsset>("Text/username.txt");
//TextAsset forbidText = GlobalManager.LoadFromFile<TextAsset>("Text/word.txt");
TextAsset nameText = Resources.Load("Text/username") as TextAsset; // 路径问题
if (nameText != null)
{
m_nickArray = nameText.text.Split(','); // 通过逗号读取出词库,后面通过逗号隔开,添加词库 写进新文本
}else
{
Debug.Log("\n 读取昵称文本失败 ");
return;
}
TextAsset forbidText = Resources.Load("Text/word") as TextAsset;
if (forbidText != null)
{
m_forbidArray = forbidText.text.Split(',');
}else
{
Debug.Log("\n 读取敏感词库文本失败 ");
return;
}
if (index == 1)
{
//CheckEqualWord(m_nickArray);
ReAddToList(m_nickArray);
GetRepeatWord(index); // 提取重复词汇
GetRepeatWord(index, true); // 提取 新词汇
return;
}else if(index == 2)
{
//CheckEqualWord(m_forbidArray);
ReAddToList(m_forbidArray);
GetRepeatWord(index); // 提取重复词汇
GetRepeatWord(index, true); // 提取 新词汇
return;
}
// 提取冲突词库,提取删除冲突后的昵称词库
if (m_nickArray != null && m_forbidArray != null)
{
CompareArray(index); // 昵称词库与 敏感词库比较
}
//CheckEqualWord(m_nickArray);
//ReAddToList(m_nickArray);
//WirteInTextFile();
//ReadTextFile();
}
void CompareArray(int index)
{
int count = 0;
int flag = -1;
List<string> m_list = new List<string>();
List<string> m_nickList = new List<string>(); // 删除后的字符串
Debug.Log("\n====== CompareArray ====== "+ m_nickArray.Length);
for (int i = 0; i < m_nickArray.Length; i++)
{
for (int j = 0; j < m_forbidArray.Length; j++)
{
if (m_nickArray[i] != null && m_forbidArray[j] != null)
{
string str = m_forbidArray[j];
if (m_nickArray[i].IndexOf(str) != -1)
{
count++;
Debug.LogFormat("\n====== 出现相同字符串为:{0}, ======= 敏感词汇为:{1} =====", m_nickArray[i], str);
m_list.Add(m_nickArray[i]);
flag = i;
}
}
}
if(i != flag)
{
m_nickList.Add(m_nickArray[i]); // 跳过 冲突字符串
}
}
Debug.Log("\n===== 出现敏感词汇的个数为:" + count);
if(index == 3)
{
GetStrifeWord(m_list.ToArray()); // 提取敏感词汇
}else if(index == 4)
{
DeleteStrifeWord(m_nickList.ToArray()); // 删除敏感词
}
}
// 检测 重复字符串
List<string> CheckEqualWord(string[] objArray)
{
int count = 0;
m_testList = new List<string>();
for (int i = 0; i < objArray.Length; i++)
{
for (int j = i + 1; j < objArray.Length; j++)
{
if (objArray[i] == objArray[j])
{
count++;
m_testList.Add(objArray[i]);
Debug.Log("\n=== 重复字符串为 ===:" + objArray[i]);
}
}
}
Debug.Log("\n=== 重复个数:" + count);
return m_testList;
}
// 重新 添加表
string[] ReAddToList(string[] objArray)
{
m_newArray = null;
list = new List<string>();
for (int i = 0; i < objArray.Length; i++)
{
if (!list.Contains(objArray[i]))
{
list.Add(objArray[i]); // 检测列表中 不存在的再添加进列表
}
}
m_newArray = list.ToArray();
Debug.Log("\n=== 重新排序 后检测重复 ===:" + m_newArray.Length);
//CheckEqualWord(m_newArray);
//SetArrayToString(m_newArray);
return m_newArray;
}
private string SetArrayToString(string[] strArray)
{
string str = string.Join(",", strArray); // 把数组 转换为字符串
//Debug.Log("\n====== 新的字符串为 =====:" + str);
return str;
}
// 写文件
void WirteInTextFile()
{
string path = Application.dataPath + m_nickPath;
Debug.Log("\n===== 文件路径 =====" + path);
FileStream file = new FileStream(path, FileMode.OpenOrCreate);
BufferedStream writer = new BufferedStream(file, 1024);
string str = SetArrayToString(m_newArray);
//string str = string.Join(",", m_newArray);
byte[] array = System.Text.Encoding.UTF8.GetBytes(str);
writer.Write(array, 0, array.Length);
writer.Flush();
writer.Close();
file.Close();
Debug.Log("\n ===== 写文件操作完成 =====");
//ReadTextFile();
}
// 读文件
void ReadTextFile()
{
List<string> m_list = new List<string>();
string path = Application.dataPath + m_nickPath;
FileStream file = new FileStream(path, FileMode.Open);
BufferedStream reader = new BufferedStream(file, 1024);
byte[] array = new byte[file.Length];
while (reader.Read(array, 0, array.Length) > 0)
{
string str = System.Text.Encoding.UTF8.GetString(array);
m_list.Add(str);
}
m_testList = m_list;
reader.Close();
file.Close();
Debug.Log("\n ===== 读文件操作完成 ===== " + m_list.Count);
string[] strArray = m_testList.ToArray();
Debug.Log("\n 读取 新数组长度为:" + strArray.Length);
CheckEqualWord(strArray);
SetArrayToString(strArray);
}
// 提取昵称/敏感词库中 重复词汇
private void GetRepeatWord(int index, bool isNew = false)
{
string name = isNew ? "新" : "重复";
string fileName = (index == 1) ? string.Format("{0}昵称词汇",name) : string.Format("{0}敏感词汇", name);
string path = string.Format("{0}/Resources/Text/{1}.txt", Application.dataPath, fileName);
FileStream file = new FileStream(path, FileMode.OpenOrCreate);
BufferedStream writer = new BufferedStream(file, 1024);
string str = "";
if (isNew)
{
m_newArray = ReAddToList((index == 1) ? m_nickArray : m_forbidArray);
str = SetArrayToString(m_newArray);
}
else
{
str = SetArrayToString(CheckEqualWord((index == 1) ? m_nickArray : m_forbidArray).ToArray());
}
//str = isNew ? SetArrayToString(m_newArray) : SetArrayToString(CheckEqualWord((index == 1) ? m_nickArray : m_forbidArray).ToArray());
byte[] array = System.Text.Encoding.UTF8.GetBytes(str);
writer.Write(array, 0, array.Length);
writer.Flush();
writer.Close();
file.Close();
Debug.Log("\n ===== 提取昵称/敏感词库中 重复词汇 完成 =====");
}
// 提取昵称中 包含的敏感词库
private void GetStrifeWord(string[] addArray)
{
string path = string.Format("{0}/Resources/Text/冲突昵称.txt", Application.dataPath); //Application.dataPath + "/Text/敏感词库.txt";
FileStream file = new FileStream(path, FileMode.OpenOrCreate);
BufferedStream writer = new BufferedStream(file, 1024);
string str = string.Join(",", addArray);
byte[] array = System.Text.Encoding.UTF8.GetBytes(str);
writer.Write(array, 0, array.Length);
writer.Flush();
writer.Close();
file.Close();
Debug.Log("\n ===== 提取与敏感词库 冲突的昵称字符串 完成 =====");
}
// 删除昵称中包含敏感词汇的字符串
private void DeleteStrifeWord(string[] m_newArray)
{
Debug.Log("\n 删除后的昵称长度为:"+ m_newArray.Length);
string path = string.Format("{0}/Resources/Text/新昵称.txt", Application.dataPath);
FileStream file = new FileStream(path, FileMode.OpenOrCreate);
BufferedStream writer = new BufferedStream(file, 1024);
string str = string.Join(",", m_newArray);
byte[] array = System.Text.Encoding.UTF8.GetBytes(str);
writer.Write(array, 0, array.Length);
writer.Flush();
writer.Close();
file.Close();
Debug.Log("\n ===== 删除 '昵称词库' 中与 '敏感词库' 冲突并提取新词库 完成 =====");
}
}
备注:
这里我是弄成一个工具,直接挂载到Unity 的工具栏中实现的。代码中之写了一个检测的案例,其他具体实现的操作,有兴趣的可自己去实现一下。~(≧▽≦)/~