การเขียน JSON ไปยังสตรีมโดยไม่บัฟเฟอร์สตริงในหน่วยความจำ

ฉันต้องการเขียน JSON ไปที่ Stream โดยสร้างเอกสารอย่างชัดเจน ตัวอย่างเช่น:

var stream = ...;
var writer = new JsonWriter(stream);

writer.BeginArray();
{
  writer.BeginObject();
  {
    writer.String("foo");
    writer.Number(1);
    writer.String("bar");
    writer.Number(2.3);
  }
  writer.EndObject();
}
writer.EndArray();

สิ่งนี้จะทำให้เกิด:

[
  {
    "foo": 1,
    "bar": 2.3
  }
]

ประโยชน์ของแนวทางนี้คือไม่จำเป็นต้องมีสิ่งใดถูกบัฟเฟอร์ในหน่วยความจำ ในสถานการณ์ของฉัน ฉันกำลังเขียน JSON จำนวนมากลงในสตรีม โซลูชันเช่น อันนี้เกี่ยวข้องกับการสร้างอ็อบเจ็กต์ทั้งหมดของคุณในหน่วยความจำ จากนั้นทำให้อ็อบเจ็กต์เป็นอนุกรมเป็นสตริงขนาดใหญ่ในหน่วยความจำ จากนั้นจึงเขียนในที่สุด สตริงนี้ไปยังสตรีมและการรวบรวมขยะ อาจมาจาก LOH ฉันต้องการให้หน่วยความจำของฉันเหลือน้อย โดยเขียนองค์ประกอบต่างๆ ในขณะที่อ่านข้อมูลจากไฟล์/DB/สตรีมอื่น ๆ

วิธีการประเภทนี้มีให้บริการในภาษา C++ ผ่านทาง ไลบรารี Rapidjson

ฉันค้นหาเรื่องนี้มาพอสมควรแล้วและยังไม่พบวิธีแก้ไข


person Drew Noakes    schedule 16.08.2013    source แหล่งที่มา


คำตอบ (1)


ปรากฎว่าฉันต้องใช้ Google นานกว่านี้อีกสักหน่อย

JSON.NET รองรับสิ่งนี้ผ่านคลาส JsonWriter

ตัวอย่างของฉันจะเขียน:

Stream stream = ...;

using (var streamWriter = new StreamWriter(stream))
using (var writer = new JsonTextWriter(streamWriter))
{
    writer.Formatting = Formatting.Indented;

    writer.WriteStartArray();
    {
        writer.WriteStartObject();
        {
            writer.WritePropertyName("foo");
            writer.WriteValue(1);
            writer.WritePropertyName("bar");
            writer.WriteValue(2.3);
        }
        writer.WriteEndObject();
    }
    writer.WriteEndArray();
}
person Drew Noakes    schedule 16.08.2013
comment
เหตุใดคุณจึงใช้ {, }s ที่ไม่จำเป็นเหล่านั้น - person I4V; 16.08.2013
comment
และเหตุใดฉันจึงควรเขียนองค์ประกอบทั้งหมดด้วยตนเองอย่างชัดเจนแทนที่จะทำ jsonSerializer.Serialize(jsonTextWriter,obj) ? - person I4V; 16.08.2013
comment
@ I4V -- {} มีไว้เพื่อให้อ่านง่ายและเป็นทางเลือก ในตัวอย่างเล็กๆ น้อยๆ พวกเขาสามารถช่วยได้จริงๆ การเขียนองค์ประกอบด้วยตนเองเป็นความคิดที่ดีหากคุณมีองค์ประกอบมากมายให้เขียนซึ่งมีรูปแบบการทำซ้ำแบบง่ายๆ ตัวอย่างเช่น หากคุณกำลังเขียน JSON ไปยังสตรีมการตอบสนอง HTTP โดยใช้องค์ประกอบ 100,000 รายการจาก SqlDataReader การเขียนในลักษณะนี้จะช่วยหลีกเลี่ยงการกดปุ่ม OutOfMemoryException และแม้ว่าคุณจะไม่มี OOME เว็บเซิร์ฟเวอร์ของคุณก็จะทำงานได้ดีขึ้นมาก ดังนั้นจึงขึ้นอยู่กับความต้องการของสถานการณ์ของคุณ - person Drew Noakes; 16.08.2013
comment
@ I4V ในกรณีของฉันฉันใช้การจัดเรียงประเภทรูปแบบผู้เยี่ยมชมโดยที่การใช้ JsonWriter ให้สิ่งที่เป็นนามธรรมที่ดี ทำให้ตัวจัดการที่แตกต่างกันสามารถเขียนสิ่งที่พวกเขาต้องการได้ - person Drew Noakes; 16.08.2013
comment
@ I4V ยิ่งไปกว่านั้นนี่เป็นวิธีการที่มีประสิทธิภาพมากกว่า การทำให้เป็นอนุกรมมักมีค่าใช้จ่ายสูงเสมอ ด้วยการเขียนเฉพาะข้อมูลที่จำเป็นด้วยตนเอง คุณสามารถหลีกเลี่ยงงานจำนวนมากได้ หลังจากที่การทำให้เป็นอนุกรมอัตโนมัติทั้งหมดจำเป็นต้องตรวจสอบคุณลักษณะบางอย่างและวิเคราะห์โครงสร้างของวัตถุซึ่งใช้เวลานานกว่าการเขียนด้วยตนเองมาก ในโปรเจ็กต์ของฉัน ฉันเขียนไฟล์ด้วยตนเองเพราะอาจใช้เวลานานและมีข้อมูลจำนวนมาก และขออภัย ฉันรู้ว่ากระทู้นี้เก่าแล้ว แต่ฉันคิดว่านี่เป็นสิ่งที่ควรค่าแก่การกล่าวถึง - person SharpShade; 30.05.2017