エラーメッセージ
JsonReaderException: After parsing a value an unexpected character was encountered: k. Path '[13].value', line 1, position 166727.
Newtonsoft.Json.JsonTextReader.ParsePostValue (System.Boolean ignoreComments) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonTextReader.Read () (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues (Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.Serialization.ObjectConstructor`1[T] creator, System.String id) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
[......]
Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Project.Scripts.Domain.Singleton.CachingData.FetchMap (System.Int32 slot) (at Assets/Project/Scripts/Domain/Singleton/CachingData.cs:136)
状況
Unityでマルチプラットフォーム対応のPC向けゲームを作っているのですが、暗号化してUTF-8でファイルに保存しておいたデータを読もうとするとMacでは復号できるのにWindowsではエラーが出てしまいました。
上記エラーメッセージでは Newtonsoftがjsonを読み込めないことが示されていますが、似たような問題で違うメッセージが出ることも考えられます。
using var fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var bytes = new byte[fs.Length]; fs.Read(bytes, 0, bytes.Length); var decrypt = Encryption.Decrypt(bytes, EncryptKey, Iv); var json = Encoding.UTF8.GetString(decrypt);
MacではUTF-8がデフォルトの文字コードでしたが、私の使っていたWindowsではShift-JISを使っていたことが原因のようでした。保存の際にはUTF-8を指定して保存していたため、文字コードが一致せず、読み込めないという状態になってしまいました。
これを解決するためには明示的に文字コードを指定する必要があります。
解決策
using var fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using var reader = new BinaryReader(fs, Encoding.UTF8); var bytes = reader.ReadBytes((int) fs.Length); var decrypt = Encryption.Decrypt(bytes, EncryptKey, Iv); var json = Encoding.UTF8.GetString(decrypt);
これで読むときも必ずUTF-8を使うことができます。もちろん書き込むときに他のEncodingを使っているならばそれに合わせたDecodingをしましょう。