Как преобразовать MemoryStream с несколькими типами данных через сервер Redis - PullRequest
1 голос
/ 12 июня 2019

Я пытаюсь отправить информацию через сервер Redis, я создаю консольное приложение с C # в VS и использую MemoryStream, который состоит из Long, String, Int и Double. На виртуальной машине под управлением Ubuntu я использую MonoDevelop для чтения информации, которую я пишу из VS MemoryStream

Я довольно новичок в передаче данных через сервер, поэтому я предпринял попытку, преобразовав мой MemoryStream в байтовый массив, а затем из этого байтового массива в String, потому что redis принимает только строковые данные, а затем я пытаясь преобразовать его обратно в исходный поток на другой консоли на виртуальной машине Ubuntu.

public void SaveBigData()
{
    var cache = RedisConnectorHelper.Connection.GetDatabase();
    long timeStamp = shortTime;
    String name = "Bob";
    int number = rnd.Next(100);
    double price = rnd.Next(20) + rnd.NextDouble();           

    binWriter.Write(timeStamp);
    binWriter.Write(name);
    binWriter.Write(number);
    binWriter.Write(price);
    binWriter.Flush();

    var testData = dataStream.ToArray();
    var value = Convert.ToBase64String(testData);
    Console.WriteLine($"Convert.ToBase64String={value}");
    cache.StringSet($"Device_Status:{numOfEntries++}", value);

}
private static int numOfEntries = 0;        
private static MemoryStream dataStream = new MemoryStream();
private static BinaryWriter binWriter = new BinaryWriter(dataStream);

При чтении данных на моей виртуальной машине мой метод выглядит следующим образом:

public void ReadData()
    {
        var cache = RedisConnectorHelper.Connection.GetDatabase();
        var devicesCount = 10;
        for (int i = 0; i < devicesCount; i++)
        {
            var value = cache.StringGet($"Device_Status:{i}");
            var redisString = Convert.FromBase64String(value);
            dataStream = new MemoryStream(redisString);
            var testPrinter = dataStream.toString();
            Console.WriteLine($"Value={value}");
            Console.WriteLine($"redisString={redisString}");
            Console.WriteLine($"testPrinter={testPrinter}");
        }
    }

Это все, что я получил, и я не уверен, как получить исходную информацию в тех же типах данных, но также иметь возможность назначать значения на виртуальной машине вместе с полученными значениями.

1 Ответ

0 голосов
/ 12 июня 2019

То, что вы пытаетесь сделать, как отмечает Джеймс Торп: сериализация.Теперь вы можете делать это вручную, но, честно говоря, это нецелесообразное использование вашего времени.Если вы хотите текстовые данные, вам, вероятно, стоит просто изучить использование Json.NET.Поскольку вопрос вызывает много шума в двоичном коде, для таких вещей вы , вероятно, хотите использовать что-то вроде protobuf.К счастью, protobuf-net существует и хорошо работает здесь;пример:

// store
using (var ms = new MemoryStream())
{
    var obj = new MyData
    {
        Name = name,
        Price = price,
        Number = number,
        TimeStamp = timeStamp,
    };
    Serializer.Serialize<MyData>(ms, obj);
    // older versions: cache.StringSet("somekey", (byte[])ms.ToArray());
    cache.StringSet("somekey", RedisValue.CreateFrom(ms));
}
// retreive
using (var ms = new MemoryStream((byte[])cache.StringGet("somekey")))
{
    var obj = Serializer.Deserialize<MyData>(ms);
    Console.WriteLine(obj.Name);
    Console.WriteLine(obj.Price);
    Console.WriteLine(obj.Number);
    Console.WriteLine(obj.TimeStamp);
}

с:

[ProtoContract]
public class MyData
{
    [ProtoMember(1)]
    public long TimeStamp { get; set; }
    [ProtoMember(2)]
    public string Name { get; set; }
    [ProtoMember(3)]
    public double Price { get; set; }
    [ProtoMember(4, DataFormat = DataFormat.ZigZag)]
    public int Number { get; set; }
}

protobuf-net и SE.Redis хорошо работают вместе - у них один и тот же автор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...