c# - 使用 JsonTextReader 或任何其他替代方法从 json 中读取特定对象作为流
问题描述
必须将大文件作为 JSON 的一部分从 HTTP Post 读取到 Web API。因为文件本身是 JSON 的一部分。例子:
{
"type": "xxxx",
//other JSON,
"attachment": {
"mimetype": "text/csv",
"extension": "csv",
"data":{a,b,c,d,f}
}
我只需要查找附件对象,但这里的“数据”再次包含大文件。可以是 csv、pdf、JSON 或图像,最重要的是大于 1GB。
根据分析,这些包装器能够阅读此内容
public class AttachmentParser
: JsonParser<Attachment>
{
public AttachmentParser(Stream json, string jsonPropertyName)
: base(json, jsonPropertyName)
{
Parse();
}
public override void Build(Attachment parsable, JsonTextReader reader)
{
if (reader.Value.Equals("extension"))
{
reader.Read();
parsable.Extention = (string)reader.Value;
}
else if (reader.Value.Equals("data"))
{
reader.Read();
parsable.Data = reader.Value;
}
}
protected override bool IsBuilt(Attachment parsable, JsonTextReader reader)
{
var isBuilt = parsable.Extention != null && parsable.Data != null;
return isBuilt || base.IsBuilt(parsable, reader);
}
private static MemoryStream SerializeToStream(object o)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
return stream;
}
}
json解析器:
public abstract class JsonParser<TParsable>
where TParsable : class, new()
{
private readonly Stream json;
private readonly string jsonPropertyName;
protected JsonParser(Stream json, string jsonPropertyName)
{
this.json = json;
this.jsonPropertyName = jsonPropertyName;
Result = new TParsable();
}
public TParsable Result { get; private set; }
public abstract void Build(TParsable parsable, JsonTextReader reader);
protected virtual bool IsBuilt(TParsable parsable, JsonTextReader reader)
{
return reader.TokenType.Equals(JsonToken.None);
}
protected void Parse()
{
using (var streamReader = new StreamReader(json))
{
using (var jsonReader = new JsonTextReader(streamReader))
{
do
{
jsonReader.Read();
if (jsonReader.Value == null || !jsonReader.Value.Equals(jsonPropertyName))
{
continue;
}
var parsable = new TParsable();
do
{
jsonReader.r;
}
while (!jsonReader.TokenType.Equals(JsonToken.PropertyName) && !jsonReader.TokenType.Equals(JsonToken.None));
do
{
Build(parsable, jsonReader);
jsonReader.Read();
}
while (!IsBuilt(parsable, jsonReader));
Result = parsable;
}
while (!jsonReader.TokenType.Equals(JsonToken.None));
}
}
}
}
查询:这里 JSONTextReader 有 jsonReader.Read() 方法,它确实逐个元素地读取,但默认情况下作为对象读取。这将在内存中,并在此操作期间增加更多的内存负载。看了看重载不包含ReadAsStream方法。
有没有办法通过不同的库或同一个库以不同的方式将大数据作为流读取(虽然没有重载)
解决方案
推荐阅读
- c# - 使用 GetSchema 获取第一个表
- azure-ad-b2c - AAD B2C:在 JWT 中为 Hasura 输出嵌套的 JSON 对象
- qt - 如何以编程方式将文本附加到 QML TextArea?
- react-native - React-Native this.props.navigation.navigate 在函数 get_id() 内不起作用
- html - 标题背景颜色不显示
- r - R中无限和的第四位小数
- php - 如何在 Wordpress 中查找 URL 的 PHP 文件
- go - 使用gob在Golang中进行通用数据解码,无法从通用接口中获取价值
- python - 我如何网页抓取仅在使用特定 chrome 扩展时出现的页面元素?
- python - 将移动数字键盘数字转换为其对应的单词 Python