File: Utils\FileUtils.cs
Web Access
Project: src\src\Microsoft.ML.TorchSharp\Microsoft.ML.TorchSharp.csproj (Microsoft.ML.TorchSharp)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.ML.Runtime;
 
namespace Microsoft.ML.TorchSharp.Utils
{
    internal static class FileUtils
    {
        private const int WriteBatchSize = 1024 * 1024;     // this size seems good on performance
        private static readonly Type[] _validTypes = new Type[]
        {
            typeof(short),
            typeof(ushort),
            typeof(int),
            typeof(uint),
            typeof(long),
            typeof(ulong),
            typeof(float),
            typeof(double),
        };
 
        /// <summary>
        /// Load a continuous segment of bytes from stream and parse them into a number array.
        /// NOTE: this function is only for little-endian storage!
        /// </summary>
        /// <typeparam name="T">should be a numeric type</typeparam>
        /// <param name="stream">the stream to read from its current position</param>
        /// <param name="numElements">expected number of parsed numbers</param>
        /// <param name="tSize">number of bytes occupied by the specified type</param>
        /// <exception cref="NotSupportedException">When the generic type T is not a valid numeric type.</exception>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="InvalidDataException">When the contents in the stream don't match the need.</exception>
        public static IEnumerable<T> LoadNumberArrayFromStream<T>(Stream stream, int numElements, int tSize)
        {
            if (stream == null || !stream.CanRead)
            {
                throw new ArgumentException($"Stream should be non-null and its stream.CanRead property should be true.");
            }
            if (!_validTypes.Contains(typeof(T)))
            {
                throw new NotSupportedException($"Type {typeof(T)} not supported in data loading.");
            }
 
            var numBytesConsumed = numElements * tSize;
            var byteBuffer = new byte[numBytesConsumed];
            var numBytesRead = stream.Read(byteBuffer, 0, numBytesConsumed);
            if (numBytesConsumed != numBytesRead)
            {
                throw new InvalidDataException(
                    $"The number of bytes read from stream is less than expected. Please check the data files.");
            }
 
            var targetBuffer = new T[numBytesConsumed / tSize];
            Buffer.BlockCopy(byteBuffer, 0, targetBuffer, 0, numBytesConsumed);
            return targetBuffer;
        }
    }
}