创建文件夹StreamingAssets,将字符123/n456/n789/n写入文件test.txt。然后把文件转换为byte数组发给服务端。再把文件里的数据读取出来赋值给一个字符串变量,然后删除StreamingAssets文件夹和里面的文件
如果文件只是读取,例如加载资源,直接用Application.streamingAssetsPath。
如果保存下载的文件,mac和windows用Application.streamingAssetsPath,ios和android用Application.persistentDataPath
如果是热更新替换资源,对于移动端需要先把文件放在Application.streamingAssetsPath,然后拷贝到Application.persistentDataPath进行资源替换。
在移动端为什么用Application.streamingAssetsPath目录而不能用Application.dataPath加自定义目录?
进过实际验证
iOS移动端StreamingAssets文件夹电脑端提前创建后,可读到。Assets目录提前在电脑创建的文件夹,移动端Application.dataPath加文件夹名读取不到。
iOS移动端StreamingAssets和Assets目录下文件夹不能代码动态创建。
结论:iOS移动端只读资源可以用Application.streamingAssetsPath(StreamingAssets文件夹在电脑端提前创建好),可读可写需求移动端需要使用Application.persistentDataPath目录。
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
//如果文件只是读取,例如加载资源,直接用Application.streamingAssetsPath。
//如果保存下载的文件,mac和windows用Application.streamingAssetsPath,ios和android用Application.persistentDataPath
//如果是热更新替换资源,对于移动端需要先把文件放在Application.streamingAssetsPath,然后拷贝到Application.persistentDataPath进行资源替换。
// 在移动端为什么用Application.streamingAssetsPath目录而不能用Application.dataPath加自定义目录?
// 进过实际验证
// iOS移动端StreamingAssets文件夹电脑端提前创建后,可读到。Assets目录提前在电脑创建的文件夹,移动端Application.dataPath加文件夹名读取不到。
// iOS移动端StreamingAssets和Assets目录下文件夹不能代码动态创建。
// 结论:iOS移动端只读资源可以用Application.streamingAssetsPath(StreamingAssets文件夹在电脑端提前创建好),可读可写需求移动端需要使用Application.persistentDataPath目录。
//创建文件夹StreamingAssets,将字符123/n456/n789/n写入文件test.txt。然后把文件转换为byte数组发给服务端。再把文件里的数据读取出来赋值给一个字符串变量,然后删除StreamingAssets文件夹和里面的文件
public class Demo : MonoBehaviour
{
string inputStr = "123/n456/n789/n";
string outputStr = "";
string outputStr2 = "";
byte[] byteData = new byte[2] { 0, 0 };
byte[] byteData2 = new byte[2] { 0, 0 };
void Start()
{
WriteFile(inputStr, StreamingAssetsPath() + "/test.txt");
outputStr = ReadFile(StreamingAssetsPath() + "/test.txt");
Debug.Log($"outputStr = {outputStr}");
StartCoroutine(UploadFileRequest(StreamingAssetsPath() + "/test.txt", "https://tttv.qiaohuapp.com/api/v2.0/games/upload"));
//删除
//DeleteDirectoryAndAllFiles(StreamingAssetsPath());
CreateDirectory(DataPath() + "/dr");
//这一句可以写入前创建出test.txt文件
WriteFile(inputStr, DataPath() + "/dr" + "/test.txt");
outputStr = ReadFile(DataPath() + "/dr" + "/test.txt");
Debug.Log($"outputStr = {outputStr}");
StartCoroutine(UploadFileRequest(DataPath() + "/dr" + "/test.txt", "https://tttv.qiaohuapp.com/api/v2.0/games/upload"));
//删除
DeleteDirectoryAndAllFiles(DataPath() + "/dr");
byteData[1] = 1;
//这一句可以写入前创建出test2.txt文件
ChangeByteToFile(DataPath() + "/dr" + "/test2.txt", byteData, byteData.Length);
byteData2 = ChangeFileToByte(DataPath() + "/dr" + "/test2.txt");
foreach (var item in byteData2)
{
Debug.Log($"byteData2 item = {item}");
}
}
public string DataPath()
{
//对应文件夹Assets
return Application.dataPath;
}
//提前手动创建treamingAssets文件夹后,再操作时的路径
public string StreamingAssetsPath()
{
//对应文件夹Assets/StreamingAssets
//mac和windows端是可读可写,ios和android端是只读
string path = "";
if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.IPhonePlayer)
{
path = "file://" + Application.streamingAssetsPath;
Debug.Log("StreamingAssetsPath WindowsEditor OR OSXEditor OR iOS = " + path);
}
else if (Application.platform == RuntimePlatform.Android)
{
path = Application.streamingAssetsPath;
Debug.Log("StreamingAssetsPath Android= " + path);
}
return path;
}
public string PersistentDataPath()
{
//移动端是可读可写,persistentDataPath文件夹是apk安装以后,才形成的一个文件夹,无法提前创建。
//下载的文件和把streamingAssetsPath文件拷贝进来后可以读写操作。
return Application.persistentDataPath;
}
//加载资源路径
public string LoadResourcesPath()
{
return StreamingAssetsPath();
}
//下载路径
public string DownLoadPath()
{
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
{
return Application.persistentDataPath;
}
else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
{
return Application.streamingAssetsPath;
}
return "";
}
public bool IsDirectoryExist(string directoryName)
{
return Directory.Exists(directoryName);
}
public void CreateDirectory(string directoryName)
{
if(!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
}
//删除文件夹前,需要先把里面的文件删除,不然会报错
public void DeleteDirectory(string directoryName)
{
Directory.Delete(directoryName);
}
/// <summary>
/// 可以一次性删掉文件夹和里面的所有文件
/// </summary>
/// <param name="directoryName"></param>
public void DeleteDirectoryAndAllFiles(string directoryName)
{
DirectoryInfo di = new DirectoryInfo(directoryName);
di.Delete(true);
}
public void MoveDirectory(string sourcePath, string targetPath)
{
Directory.Move(sourcePath, targetPath);
}
public bool IsFileExist(string fileName)
{
return File.Exists(fileName);
}
public void CreateFile(string fileName)
{
if(!File.Exists(fileName))
{
File.Create(fileName);
}
}
public void DeleteFile(string fileName)
{
File.Delete(fileName);
}
public void MoveFile(string sourcePath, string targetPath)
{
File.Move(sourcePath, targetPath);
}
public void WriteFile(string str, string fileName)
{
try
{
StreamWriter sw = new StreamWriter(fileName);
sw.Write(str);
sw.Close();
}
catch (System.Exception ex)
{
Debug.Log($"error = {ex}");
}
}
public string ReadFile(string fileName)
{
string str = "";
try
{
StreamReader sr = new StreamReader(fileName);
//如果内容为空,返回为-1
if (sr.Peek() != -1)
{
str = sr.ReadToEnd();
sr.Close();
}
}
catch (System.Exception ex)
{
Debug.Log($"error = {ex}");
}
return str;
}
//接收到byte数组数据,转换为文件(例如txt文件,mp3文件,jpg文件)
public void ChangeByteToFile(string fileName, byte[] bytes, int length)
{
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
fs.Write(bytes, 0, length);
fs.Close();
}
//把文件(例如txt文件,mp3文件,jpg文件)转为byte数组数据,发送给服务端
public byte[] ChangeFileToByte(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
//获取FileStream的长度,开辟对应的byte内存空间
byte[] data = new byte[fs.Length];
//因为data是数组,数组是引用类型,这里data作为参数,fs.Read运行后,外层的data也能获取到对应数据,所以这里可以return data数据
fs.Read(data, 0, data.Length);
fs.Close();
return data;
}
/// <summary>
/// 将文件发送给服务端(字节流形式)
/// </summary>
/// <param name="filePath"></param>
/// <param name="url"></param>
/// <returns></returns>
public IEnumerator UploadFileRequest(string filePath, string url)
{
WWWForm form = new WWWForm();
form.AddBinaryData("file", ChangeFileToByte(filePath));
string token = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMTMxNTk1NSIsInFpYW9odU5ld1VzZXIiOjAsInVzZXJfbmFtZSI6IjE4MjE4MjQyMzM3IiwibW9iaWxlIjoiMTgyMTgyNDIzMzciLCJoYXNSaWdodCI6MCwidmVyc2lvbiI6IiIsImF1dGhvcml0aWVzIjpbIk4vQSJdLCJjbGllbnRfaWQiOiJxaC10ZXNsYS1hcHAiLCJhdWQiOlsicWgtZWluc3RlaW4tcmVzdCIsInFoLXF1ZXRlbGV0LXJlc3RkYXRhIiwicWgtdGVzbGEtcmVzdCJdLCJzY29wZSI6WyJ0cnVzdCJdLCJuaWNrbmFtZSI6IueUqOaItzAzM0RDRjAiLCJhdXRob3JTdGF0dXMiOiIwIiwiZXhwIjoxNjU0MTM3NzYxLCJ1Y29kZSI6IjE2OTQxNzA2MDIiLCJqdGkiOiJhNzJmY2Y5Mi01NzUwLTQyMzktYjVlMi02Y2ViYzk0YjM4NTQifQ.P5STi7KuE78sjpDRIIIjDtmZ8sdv54yHRNDn0Dbmh0g";
UnityWebRequest uwr = UnityWebRequest.Post(url, form);
uwr.SetRequestHeader("Authorization", token);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.LogError("文件上传失败 = " + uwr.error);
}
else
{
Debug.Log("文件上传成功,结果 = " + uwr.downloadHandler.text);
}
}
}