繁体   English   中英

值已读取,或尝试从 Stream 读取时没有值

[英]Value already read, or no value when trying to read from a Stream

我已经尝试了很长时间,但它一直给我一个错误。 我有一个应该代表 nbt 文档的字节数组。 我想将其转换为带有库的 c# object:fNbt。

这是我的代码:

byte[] buffer = Convert.FromBase64String(value);
byte[] decompressed;

using (var inputStream = new MemoryStream(buffer))
{
    using var outputStream = new MemoryStream();

    using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress, leaveOpen: true))
    {
        gzip.CopyTo(outputStream);
    }

    fNbt.NbtReader reader = new fNbt.NbtReader(outputStream, true);
    var output = reader.ReadValueAs<AuctionItem>(); //Error: Value already read, or no value to read.
    return output;
}

当我尝试这个时,它有效:

            decompressed = outputStream.ToArray();
            outputStream.Seek(0, SeekOrigin.Begin);
            outputStream.Read(new byte[1000], 0, decompressed.Count() - 1);

但是当我尝试这个时,它不会:

            outputStream.Seek(0, SeekOrigin.Begin);
            fNbt.NbtReader reader = new fNbt.NbtReader(outputStream, true);
            reader.ReadValueAs<AuctionItem>();

NbtReader ,像大多数 stream 阅读器一样,从您给它的任何 stream 的当前position 开始读取。 由于您刚刚完成了对outputStream的写入,因此 position 是流的结束。 这意味着在这一点上没有什么可读的。

解决方案是在读取outputStream之前将outputStream返回到开头:

outputStream.Seek(0, SeekOrigin.Begin); // <-- seek to the beginning    

// Do the read
fNbt.NbtReader reader = new fNbt.NbtReader(outputStream, true);
var output = reader.ReadValueAs<AuctionItem>(); // No error anymore
return output;

解决方法如下。 NbtReader.ReadValueAs 不将 nbtCompound 或 nbtList 视为值。 我做了这个小阅读器,但还没有完成(一旦完成,我将更新代码)。

    public static T ReadValueAs<T>(string value) where T: new()
    {
        byte[] buffer = Convert.FromBase64String(value);

        using (var inputStream = new MemoryStream(buffer))
        {
            using var outputStream = new MemoryStream();

            using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress, leaveOpen: true))
            {
                gzip.CopyTo(outputStream);
            }
            outputStream.Seek(0, SeekOrigin.Begin);

            return new EasyNbt.NbtReader(outputStream).ReadValueAs<T>();
        }
    }

这是 NbtReader:

    private MemoryStream MemStream { get; set; }

    public NbtReader(MemoryStream memStream)
    {
        MemStream = memStream;
    }

    public T ReadValueAs<T>() where T: new()
    {
        return ReadTagAs<T>(new fNbt.NbtReader(MemStream, true).ReadAsTag());
    }

    private T ReadTagAs<T>(fNbt.NbtTag nbtTag)
    {
        //Reads to the root and adds to T...
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM