How to retrieve the file size of a file in VPP

Vote:
 

Hi,

I've uploaded a document to the VPP, and I've since linked to it in a page. Im trying to display the file extension and file size next to the link. I've been searching thorugh the forums and the closest I've come is the following:-

filepath = "\globalassets\documents\gt8amniocentesis0111.pdf"

var file = HostingEnvironment.VirtualPathProvider.GetFile(filepath) as UnifiedFile;

return file.Length / 1024 + "Kb"

Except each time I try to use this I get the error:-

#207895
Oct 08, 2019 10:20
Vote:
 

You could hook up to the content events like e.g. SavingContent and use something like Stream stream = imageFile.BinaryData.OpenRead(), stream.GetFileSize() to set the value of a property on your ContentType? Or just an extension method on your MediaData

        /// <summary>
        ///     Gets the size of the file.
        /// </summary>
        /// <param name="media">The media.</param>
        /// <returns>System.String.</returns>
        public static string GetFileSize(this MediaData media)
        {
            if (media == null)
            {
                return string.Empty;
            }

            using (Stream stream = media.BinaryData.OpenRead())
            {
                return stream.GetFileSize();
            }
        }

        /// <summary>
        ///     Gets the size of the file.
        /// </summary>
        /// <param name="stream"></param>
        /// <returns>System.String.</returns>
        public static string GetFileSize(this Stream stream)
        {
            return stream == null ? string.Empty : BytesToString(stream.Length);
        }

        /// <summary>
        ///     Convert bytes to string.
        /// </summary>
        /// <param name="byteCount">The byte count.</param>
        /// <returns>System.String.</returns>
        public static string BytesToString(long byteCount)
        {
            string[] suf = { " bytes", " KB", " MB", " GB", " TB", " PB", " EB" };      //Longs run out around EB

            if (byteCount == 0)
            {
                return "0" + suf[0];
            }

            try
            {
                long bytes = Math.Abs(byteCount);
                int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
                double num = Math.Round(bytes / Math.Pow(1024, place), 1);
                return (Math.Sign(byteCount) * num) + suf[place];
            }
            catch (OverflowException)
            {
                return string.Empty;
            }
        }
#207896
Edited, Oct 08, 2019 10:46
Vote:
 

If your files are represented by a class inheriting from, MediaData, add:

public string GetFileSize()
{
    using (var stream = BinaryData.OpenRead())
    {
        return stream.Length.ToFileSize(0);
    }
}


And even better, do as Jeroen Stemerdink proposes.

#207897
Edited, Oct 08, 2019 10:44
Vote:
 

Hey @Kieutrang

We've achieved what you're trying to do, by using concepts from this post https://episerverblog.wordpress.com/2014/06/11/displaying-file-size-for-your-mediadata/

Plus we used the more user-friendly BytesToString method that @Jeroen posted above.

We used an Interface like this one...

namespace Episerver.WebApp.Models.Media
{
    public interface IContentMediaMetaData : IContentMedia
    {
        string FileExtension { get; set; }

        int FileSize { get; set; }
    }
}

Then add an InitializableModule to catch the CreatingContent and SavingContent Events for classes that inherit our Interface

namespace Episerver.WebApp.Business.Initialization
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class ContentMediaInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            var eventRegistry =
            ServiceLocator.Current.GetInstance<IContentEvents>();

            eventRegistry.CreatingContent += OnCreatingContent;
            eventRegistry.SavingContent += OnSavingContent;

        }

        public void Preload(string[] parameters)
        {
        }

        public void Uninitialize(InitializationEngine context)
        {
            var eventRegistry =
            ServiceLocator.Current.GetInstance<IContentEvents>();

            eventRegistry.CreatingContent -= OnCreatingContent;
            eventRegistry.SavingContent -= OnSavingContent;

        }

        private void OnSavingContent(object sender, ContentEventArgs e)
        {
            MediaHelpers.SetFileMetaData(e.Content as IContentMediaMetaData);
        }

        private static void OnCreatingContent(object sender, ContentEventArgs e)
        {
            MediaHelpers.SetFileMetaData(e.Content as IContentMediaMetaData);
        }
    }
}

And the MediaHelper.SetFileMetaData method sets the MetaData Properties on the Object that's passed in.

#207967
Edited, Oct 09, 2019 14:36