c# - tweet - ¿Cómo deserializar múltiples objetos de una secuencia json?
twitter streaming api track (2)
Usé la biblioteca Json.Net y esta clase de extensión que hace uso de DynamicObject
para analizar los objetos json de transmisión
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://stream.twitter.com/1/statuses/sample.json");
webRequest.Credentials = new NetworkCredential("...", "......");
webRequest.Timeout = -1;
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader responseStream = new StreamReader(webResponse.GetResponseStream());
string line;
while (true)
{
line = responseStream.ReadLine();
dynamic obj = JsonUtils.JsonObject.GetDynamicJsonObject(line);
if(obj.user!=null)
Console.WriteLine(obj.user.screen_name + " => " + obj.text);
}
Ok, he hecho preguntas sobre algo como esto antes, pero este es un tema diferente, así que creo que debería hacer un nuevo tema al respecto. Lo siento si esto es algo que no debería haber hecho ...
De todas formas:
Actualmente estoy leyendo un feed de Twitter e intento convertirlo en objetos perdidos (de estado). El código que tengo ahora es el siguiente, pero falla:
webRequest = (HttpWebRequest)WebRequest.Create(stream_url);
webRequest.Credentials = new NetworkCredential(username, password);
webRequest.Timeout = -1;
webResponse = (HttpWebResponse)webRequest.GetResponse();
Encoding encode = Encoding.GetEncoding("utf-8");
responseStream = new StreamReader(webResponse.GetResponseStream(), encode);
int i = 0;
//Read the stream.
while (_running)
{
jsonText = responseStream.ReadLine();
byte[] sd = Encoding.Default.GetBytes(jsonText);
stream.Write(sd, i, i + sd.Length);
try
{
status s = json.ReadObject(stream) as status;
if (s != null)
{
//write s to a file/collection or w/e
i = 0;
}
}
catch
{
}
}
La idea es: copiar la secuencia en otra secuencia. y sigue intentando leerlo hasta que se descubra un objeto de estado. Esto fue para evitar que la corriente fuera pequeña, por lo que tuvo la oportunidad de crecer. Por supuesto, la transmisión no siempre comienza al comienzo de un objeto, o puede estar dañada.
Ahora encontré el método IsStartObject
, y creo que debería usarlo. Aunque no tengo experiencia con las transmisiones y nunca puedo encontrar un buen ejemplo de cómo usar esto.
¿Hay alguien que pueda explicarme cómo leer múltiples objetos de la secuencia para que pueda escribirlos en una lista o w / e? Realmente no puedo encontrar buenos ejemplos en los internets ...
¡Muchas gracias por intentarlo!
Esta es una implementación de la sugerencia de LB para dividir al contar el nivel de anidación de {y}.
public static IEnumerable<string> JsonSplit(this StreamReader input, char openChar = ''{'', char closeChar = ''}'',
char quote=''"'', char escape=''//')
{
var accumulator = new StringBuilder();
int count = 0;
bool gotRecord = false;
bool inString = false;
while (!input.EndOfStream)
{
char c = (char)input.Read();
if (c == escape)
{
accumulator.Append(c);
c = (char)input.Read();
}
else if (c == quote)
{
inString = !inString;
}
else if (inString)
{
}
else if (c == openChar)
{
gotRecord = true;
count++;
}
else if (c == closeChar)
{
count--;
}
accumulator.Append(c);
if (count != 0 || !gotRecord) continue;
// now we are not within a block so
string result = accumulator.ToString();
accumulator.Clear();
gotRecord = false;
yield return result;
}
}
Aquí hay una prueba
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
string text = "{/"a/":1}{/"b/":/"hello/"}{/"c/":/"oh}no!/"}{/"d/":/"and///"also!/"}";
var reader = From.GenerateStreamFromString(text);
var e = MyJsonExtensions.JsonSplit(reader).GetEnumerator();
e.MoveNext();
Assert.AreEqual("{/"a/":1}", e.Current);
e.MoveNext();
Assert.AreEqual("{/"b/":/"hello/"}", e.Current);
e.MoveNext();
Assert.AreEqual("{/"c/":/"oh}no!/"}", e.Current);
e.MoveNext();
Assert.AreEqual("{/"d/":/"and///"also!/"}", e.Current);
}
}
La implementación de GenerateStreamFromString está aquí