Unity HoloLens 2项目中FileStream生成不完整JSON文件问题
解决HoloLens 2 Unity项目中JSON文件写入截断问题
结论
是的,替换为UWP原生文件操作API是解决该问题的有效方案。Unity的FileStream在UWP(HoloLens基于UWP)环境下,可能存在底层缓冲区未完全刷新到磁盘就结束操作的情况,导致文件截断。
原代码的潜在问题
- 虽然
using块会自动释放FileStream,但UWP文件系统基于WinRT,Unity的FileStream封装可能存在同步写入未真正完成的情况,导致部分数据滞留在缓冲区未写入磁盘。 - 多次调用
DateTime.Now生成文件名,极端情况下可能出现同一秒内文件名重复(虽非截断直接原因,但建议优化)。
解决方案:使用UWP原生文件操作API
以下是适配HoloLens的异步写入实现,确保数据完整写入:
using System; using System.IO; using System.Runtime.Serialization.Json; using System.Threading.Tasks; using UnityEngine; using Windows.Storage; public class DataSaver : MonoBehaviour { private DataFieldCategory currentCategory; // 异步保存方法,确保写入操作完全完成 public async Task SerializeReportToJSONAsync() { // 定位到根节点 while (currentCategory.parentCategory != null) { currentCategory = currentCategory.parentCategory; } // 生成唯一文件名(单次获取时间戳避免重复) var timestamp = DateTime.Now; var fileName = $"InspectionData{timestamp:yyyy-MM-dd-HH-mm-ss}.json"; // 获取UWP本地存储文件夹(对应Unity的Application.persistentDataPath) StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile file = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); // 先序列化到内存流,确保数据完整后再写入磁盘 using (MemoryStream ms = new MemoryStream()) { DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(DataFieldCategory)); dcs.WriteObject(ms, currentCategory); ms.Position = 0; // 重置流指针到起始位置 // 异步写入文件并强制刷新缓冲区 using (Stream fileStream = await file.OpenStreamForWriteAsync()) { await ms.CopyToAsync(fileStream); await fileStream.FlushAsync(); } } } // Unity中可直接调用的触发方法(如按钮点击) public void TriggerSave() { _ = SerializeReportToJSONAsync(); // 如需处理异常,可添加try/catch: // try { await SerializeReportToJSONAsync(); } catch (Exception e) { Debug.LogError(e); } } }
关键优化点
- UWP原生API:使用
StorageFile和异步操作,适配HoloLens的文件系统,确保写入操作完全完成。 - 内存中转:先将数据序列化到
MemoryStream,再复制到文件流,避免序列化过程中直接写入磁盘可能出现的中断。 - 强制刷新:显式调用
FlushAsync(),确保所有缓冲区数据写入磁盘。 - 文件名优化:单次获取时间戳生成文件名,避免重复。
额外注意事项
- 确认
DataFieldCategory类已正确标记[DataContract]和[DataMember]属性,否则序列化会丢失数据(模拟器正常但设备异常的情况少见,但需排查)。 - HoloLens应用默认拥有本地存储权限,若写入其他位置需在UWP包清单中添加对应权限。
- 若数据量较大,建议在后台线程执行序列化操作,避免阻塞Unity主线程(注意访问
currentCategory的线程安全)。
内容的提问来源于stack exchange,提问作者CocoaMilka
相关产品推荐
相关产品推荐

