Unity 数据读取|(二)多种方式读取文本文件

2024-01-18 19:14:07 浏览数 (1)

1.前言

  • 在Unity3D中,我们经常会需要在本地或者服务器上读取游戏数据,Unity中读取文件的方式有很多种,写下此文章以做总结。

2.读取类型

2.1 TextAsset

  • TextAsset是Unity 提供的一个文本对象,它可以通过Resources.Load 或者 AssetBundle 来读取数据。
  • 它支持读取的文本格式包括 .txt .html .htm .bytes .json .csv .yaml .fnt
代码语言:javascript复制
using UnityEngine;
 
public class LoadTextAsset : MonoBehaviour
{
    private void Start()
    {
        string mystr = Resources.Load<TextAsset>("Text/text").text;
        Debug.Log(mystr);
    }
}

2.2 Resources

  • Resources 类允许查找和访问包括资产在内的对象。
  • 可以通过 Resources.Load 函数访问 Assets 文件夹中任何位置名为“Resources”的文件夹中的所有资源。可能存在多个“资源”文件夹,并且在加载对象时将检查每个文件夹。
  • 注意事项:
    • Resources类只能读取名为“Resources”的文件夹里的资源,注意是复数形式。
    • Resources文件夹需要用户自己新建,可以放在Asset文件夹里任意层级的子目录中,若在不同目录下有多个“Resources”文件夹,加载某个指定资源时每一个“Resources”文件夹都会被检查。因此建议项目中只创建一个名为“Resources”的文件夹,且放在Asset文件夹的根目录下。
    • Unity打包发布时,Resources文件夹里的资源会被打入包中。
    • Resources类加载资源时,使用”Resources”文件夹开始的相对路径,且不包含资源的扩展名。如要加载Asset/Resources/Images/10.jpg资源,加载路径应该写”Images/10”。
代码语言:javascript复制
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void Start() {
        GameObject go = GameObject.CreatePrimitive(PrimitiveType.Plane);
        Renderer rend = go.GetComponent<Renderer>();
        rend.material.mainTexture = Resources.Load("glass") as Texture;
    }
}

2.3 FileStream

  • FileStream对象表示在磁盘或网络路径上指向文件的流。这个类提供了在文件中读写字节的方法,但经常使用StreamReader或 StreamWriter执行这些功能。这是因为FileStream类操作的是字节和字节数组,而Stream类操作的是字符数据。
  • 如果你是准备读取byte数据的话,用StreamReader读取然后用 System.Text.Encoding.Default.GetBytes转化的话,如下,则可能出现数据丢失的情况,如byte数据的个数不对等。因此操作byte数据时要用FileStream。 string textContent = fileStream.ReadToEnd();byte[] bytes = System.Text.Encoding.Default.GetBytes(textContent); 字符数据易于使用, 但是有些操作,比如随机文件访问(访问文件中间某点的数据),就必须由FileStream对象执行.
代码语言:javascript复制
using (FileStream fsRead = new FileStream(@"D:1.txt", FileMode.Open))
{
    int fsLen = (int)fsRead.Length;
    byte[] heByte = new byte[fsLen];
    int r = fsRead.Read(heByte, 0, heByte.Length);
    string myStr = System.Text.Encoding.UTF8.GetString(heByte);
} 

2.4 StreamReader

  • C#中的StreamReader类用于从文本文件中读取字符流。它提供了一种方便的方法来按行读取文本文件的内容。StreamReader类位于System.IO命名空间下,可以通过使用using指令引入该命名空间来使用StreamReader类。以下是StreamReader类的一些常用方法和功能:
    • ReadLine()方法:按行读取文件内容,每次读取一行。该方法返回一个字符串,表示读取的那一行内容。如果没有更多的行可读,则返回null。
代码语言:javascript复制
using (StreamReader reader = new StreamReader("file.txt"))  
{  
    string line;  
    while ((line = reader.ReadLine()) != null)  
    {  
        Console.WriteLine(line);  
    }  
}
  • ReadToEnd()方法:读取整个文件的内容,并将其作为字符串返回。该方法会一次性读取整个文件,因此适用于较小的文件。
代码语言:javascript复制
using (StreamReader reader = new StreamReader("file.txt"))  
{  
    string content = reader.ReadToEnd();  
    Console.WriteLine(content);  
}

2.5 WWW(已过时)

  • WWW类是一个用于进行HTTP请求的工具类,它基于HTTP协议,使用多种方式传输数据。WWW类在Unity中主要支持GET和POST方式。GET方式将请求附加在URL后面,而POST方式则是通过FORM的形式提交。从安全角度来看,POST方式比GET方式安全性更高,因此在实际使用中建议更多选择POST方式。然而,GET方式最多能传递1024个字节,而POST方式理论上没有限制。此外,Unity的WWW类还支持使用Get和Post方式进行表单的上传。在Unity中,使用WWW类可以方便地从网络上动态地下载图片、声音、视频资源等等。
代码语言:javascript复制
 public static IEnumerator Load()
    {
        yield return null;       
        www = new WWW(xmlPath);
        while (!www.isDone)
        {
            yield return null;
        }
       string contentText = www.text;
    }

2.6 UnityWebRequest

  • WWW和UnityWebRequest都用于处理Http请求,UnityWebRequest是后面出的用于替代WWW的模块。相比于WWW,UnityWebRequest支持设置timeout超时时间,支持断点续传,在一些复杂操作上也有更好的表现。
  • 结构:
    • UploadHandler: 处理数据到服务器的传输
    • DownloadHandler: 处理从服务器接收的数据的接收、缓冲和后处理
    • UnityWebRequest: 管理上面两个对象
  • Get()
代码语言:javascript复制
    private IEnumerator Get()
    {
        var request = UnityWebRequest.Get("http://www.baidu.com");
        yield return request.SendWebRequest();
        if (request.isHttpError || request.isNetworkError)
        {
            Debug.LogError(request.error);
        }
        else
        {
            Debug.Log(request.downloadHandler.text);
        }
    }
  • Post()
代码语言:javascript复制
    private IEnumerator Post()
    {
    	//这里使用WWWForm来构建键值对。和WWW的使用是一致的
        WWWForm form = new WWWForm();
        form.AddField("key","value");
        UnityWebRequest webRequest = UnityWebRequest.Post("http://www.baidu.com",form);
        
        yield return webRequest.SendWebRequest();
        
        if (webRequest.isHttpError || webRequest.isNetworkError)
        {
            Debug.LogError(webRequest.error);
        }
        else
        {
            Debug.Log(webRequest.downloadHandler.text);
        }
    }
  • 显示进度
代码语言:javascript复制
    private IEnumerator GetShowProgress()
    {
        UnityWebRequest request = UnityWebRequest.Get("www.baidu.com");
        request.SendWebRequest();
        while (!request.isDone)
        {
            Debug.Log($"{GetType()} progress:{request.downloadProgress}");
            yield return null;
        }
		
		Debug.Log($"{GetType()} progress:{request.downloadProgress}");

        if (request.isNetworkError || request.isHttpError)
        {
            Debug.LogError($"{GetType()} error:{request.error}");
        }
        else
        {
            Debug.Log($"{GetType()} text:{request.downloadHandler.text}");
            Debug.Log($"{GetType()} bytes.length:{request.downloadHandler.data.Length}");
        }
    }

2.7 File

  • File类提供了一些用于文件操作的功能,包括读取和写入文件。
  • 读取文件:使用File.ReadAllText()方法可以读取文本文件的内容,该方法需要提供文件路径作为参数。例如,要读取名为"test.txt"的文本文件。
代码语言:javascript复制
string filePath = "Assets/test.txt";  
string fileContent = File.ReadAllText(filePath);  
Debug.Log(fileContent);
  • 写入文件:使用File.WriteAllText()方法可以将文本内容写入到文件中,该方法需要提供文件路径和要写入的内容作为参数。例如,要将名为"test.txt"的文本文件中写入一些内容。
代码语言:javascript复制
string filePath = "Assets/test.txt";  
string contentToWrite = "Hello, world!";  
File.WriteAllText(filePath, contentToWrite);

3.区别

3.1 FileStream和StreamReader区别

  • 类型FileStream 是字节流,而 StreamReader 是字符流。
  • 读取方式FileStream 读取文件内容时通常以字节为单位进行处理,而 StreamReader 则以字符为单位读取。
  • 用途FileStream 更适用于处理二进制文件或非文本文件,而 StreamReader 更适用于处理文本文件。
  • 性能:对于大文件,使用 FileStream 逐个字节地读取文件可能会导致性能问题,而 StreamReader 可以更高效地读取文本文件。
  • 总之,FileStreamStreamReader 都是用于处理流数据的类,但它们的使用方式和适用场景有所不同。如果您需要处理文本文件,使用 StreamReader 可能更合适。如果您需要处理二进制文件或需要更细粒度的控制,使用 FileStream 可能更适合。

3.2 WWW和UnityWebRequest区别

  • 接口设计:
    • WWW模块的接口设计较早,相对简单,主要基于Http协议进行封装。
    • UnityWebRequest对WWW进行了改进和优化,提供了更强大和灵活的接口,可以更好地处理各种网络请求和数据传输。
  • 功能特性:
    • WWW模块主要支持GET和POST请求,对于PUT和DELETE等其他HTTP方法支持不够完善。
    • UnityWebRequest支持多种HTTP方法,包括PUT、DELETE、HEAD等,还支持自定义HTTP方法。
    • UnityWebRequest还提供了对HTTP头部的自定义设置,可以更好地控制请求和响应的头部信息。
  • 数据处理:
    • WWW模块对于下载的数据处理主要是以字符串形式进行,对于二进制数据需要额外转换。
    • UnityWebRequest支持直接下载二进制数据,无需进行转换,同时也可以直接读取和处理JSON、XML等其他数据格式。
  • 效率优化:
    • UnityWebRequest在处理网络请求时,采用了更高效的异步方式,可以减少阻塞主线程的情况。
    • UnityWebRequest还对数据缓存进行了优化,减少了不必要的网络请求和数据读取。
  • 垃圾回收(GC)性能:
    • WWW模块在处理网络请求时,会产生大量的临时对象,导致频繁的垃圾回收,可能会影响性能。
    • UnityWebRequest通过优化内部实现,减少了临时对象的产生,降低了垃圾回收的频率,从而提高了性能。
  • 综上所述,UnityWebRequest在功能特性、数据处理、效率优化和使用场景等方面都优于WWW模块。在选择使用WWW或UnityWebRequest时,建议考虑项目的需求和性能要求,选择最适合的模块。

0 人点赞