DateTime (प्रत्येक टाइमस्टैम्प तरह यूटीसी का है) की एक बड़ी सरणी को क्रमबद्ध करते समय मुझे एक अजीब समस्या का सामना करना पड़ रहा है। मैं निम्नलिखित चरणों के साथ आगे बढ़ा:

  • प्रत्येक DateTime को long के माध्यम से DateTime.ToBinary() टाइप करने के लिए कनवर्ट करें
  • बफ़र के माध्यम से long[] को byte[] में बदलें।ब्लॉककॉपी
  • फ़ाइल स्ट्रीम में बाइट सरणी लिखें
  • फ़ाइल स्ट्रीम के माध्यम से बाइट सरणी में पढ़ें
  • byte[] को long[] में Buffer.BlockCopy के माध्यम से बदलें
  • प्रत्येक long को DateTime.FromBinary(long) के माध्यम से वापस दिनांक समय में बदलें

मुद्दा यह है कि दिनांक समय मूल सरणी और अंतिम सरणी के बीच मिलान नहीं कर रहे हैं। वास्तव में कुछ टाइम स्टैम्प वर्ष 2059 या उसके बाद के रूप में दिखाई देते हैं जब मूल सरणी में अतीत के समय टिकटों को सख्ती से शामिल किया गया था।

मैं विंडोज 10 में अपनी स्थानीय मशीन पर पूरी प्रक्रिया चलाता हूं इसलिए कोई समय क्षेत्र के मुद्दे नहीं होने चाहिए और न ही अंतहीनता के मुद्दे। क्या कोई मदद कर सकता है?

इस प्रकार मैं DateTime प्रकार के समय टिकटों को long[] में परिवर्तित करता हूं:

var dataCollection = new DataCollection(header.DataProviderId, DateTimeKind.Utc, header.Symbol, header.QuoteType, header.Compression)
        {
            TimeStamps = quotes.Select(x => x.TimeStamp.ToBinary()).ToArray(),
            Bid = quotes.Select(x => x.Bid).ToArray(),
            Ask = quotes.Select(x => x.Ask).ToArray()
        };

long[] -> byte[] और पीछे के बीच रूपांतरण यहां दिए गए हैं:

public static byte[] SerializeBlockCopy<T>(Array sourceArray, long sourceStartIndex, long numberItemsToSerialize)
    {
        var targetArraySize = numberItemsToSerialize * Marshal.SizeOf(typeof(T));
        var targetArray = new byte[targetArraySize];
        Buffer.BlockCopy(sourceArray, (int)sourceStartIndex, targetArray, 0, (int)targetArraySize);
        return targetArray;
    }

    public static T[] DeserializeBlockCopy<T>(byte[] sourceArray)
    {
        var targetArraySize = sourceArray.Length / Marshal.SizeOf(typeof(T));
        var targetArray = new T[targetArraySize];
        Buffer.BlockCopy(sourceArray, 0, targetArray,0, sourceArray.Length);
        return targetArray;
    }
0
Matthias Wolf 22 जिंदा 2020, 09:18

1 उत्तर

सबसे बढ़िया उत्तर

मुझे कोई त्रुटि नहीं दिख रही है। यहां एक उदाहरण कार्यक्रम है जिसे मैंने आपके तरीकों से परीक्षण किया है और उन्होंने उम्मीद के मुताबिक काम किया है:

public static void Main()
{
    var random = new Random();
    var sourceDates = Enumerable.Range(1, 100)
        .Select(i => DateTime.UtcNow.Add(TimeSpan.FromDays(random.Next(-1000, 1000))))
        .ToList();

    var values = sourceDates.Select(date => date.ToBinary()).ToArray();
    var asBytes = SerializeBlockCopy(values, 0, values.Length);
    var filename = Path.GetTempFileName();
    WriteToFile(asBytes, filename);

    var bytesFromFile = ReadFromFile(filename);
    var back = DeserializeBlockCopy<long>(bytesFromFile);
    File.Delete(filename);
    var destinationValues = back.Select(value => DateTime.FromBinary(value)).ToList();
    var pairs = sourceDates.Zip(destinationValues, (s, d) => (s, d));

    foreach (var pair in pairs)
    {
        Console.WriteLine($"{pair.s} -> {pair.d}");
    }

    Console.WriteLine($"Both are equal: {sourceDates.SequenceEqual(destinationValues)}");
}

public static void WriteToFile(byte[] source, string filename)
{
    using (var writer = new FileStream(filename, FileMode.Truncate, FileAccess.Write))
    {
        writer.Write(source, 0, source.Length);
    }
}

public static byte[] ReadFromFile(string filename)
{
    return File.ReadAllBytes(filename);
}

थोड़े से सुधार के लिए आप अपनी क्रमबद्ध विधि के हस्ताक्षर को इसमें बदल सकते हैं:

public static byte[] SerializeBlockCopy<T>(T[] sourceArray, long sourceStartIndex, long numberItemsToSerialize)

फिर आपको सामान्य तर्क प्रदान करने की आवश्यकता नहीं है, कारण प्रकार अनुमान कूदता है, लेकिन यह आपकी त्रुटि की व्याख्या नहीं करेगा।

1
Oliver 22 जिंदा 2020, 06:53