6

I'm looking for a good way to get filesize from the Microsoft.SharePoint.Client.File object.

The Client object does not have a Length member.

I tried this:

foreach (SP.File file in files)
{
    string path = file.Path;
    path = path.Substring(this.getTeamSiteUrl().Length);
    FileInformation fileInformation = SP.File.OpenBinaryDirect(this.Context, path);
    using (MemoryStream memoryStream = new MemoryStream())
    {
        CopyStream(fileInformation.Stream, memoryStream);
        file.Size = memoryStream.Length;
    }
}

Which gave me a length through using the MemoryStream, but it's not good for performance. This file also does not belong to a document library. Since it's an attached file, I can't convert it to a ListItem object using ListItemAllFields. If I could convert it to a ListItem, I could get its size using: ListItem["File_x0020_Size"]

How do I get the filesize of the Client object in SharePoint using C#?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
user834964
  • 103
  • 1
  • 1
  • 7

3 Answers3

6

Load the File_x0020_Size field information to get it.

This is what I do when I want to list all the files in a Sharepoint 2010 folder:

//folderPath is something like /yoursite/yourlist/yourfolder
Microsoft.SharePoint.Client.Folder spFolder = _ctx.Web.GetFolderByServerRelativeUrl(folderPath);

_ctx.Load(spFolder);
_ctx.ExecuteQuery();

FileCollection fileCol = spFolder.Files;
_ctx.Load(fileCol);
_ctx.ExecuteQuery();

foreach (Microsoft.SharePoint.Client.File spFile in fileCol)
{
    //In here, specify all the fields you want retrieved, including the file size one...
    _ctx.Load(spFile, file => file.Author, file => file.TimeLastModified, file=>file.TimeCreated, 
                            file => file.Name, file => file.ServerRelativeUrl, file => file.ListItemAllFields["File_x0020_Size"]);
    _ctx.ExecuteQuery();

    int fileSize = int.Parse((string)spFile.ListItemAllFields["File_x0020_Size"]);
}

_ctx is obviously the ClientContext you have initiated.

Here's an extended list of all Sharepoint internal fields

Francis Ducharme
  • 4,848
  • 6
  • 43
  • 81
0

I don't know if this question was ever solved, but for the people who are looking for an answer (like I did) :

... CODE FOR GETTING THE SP.FILE ...

SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(ctx, mySPFile.ServerRelativeUrl);
byte[] bodyString = ReadToEnd(fileInfo.Stream);
int length = bodyString.Length;
Console.Write(length.ToString());

... DO THE OTHER STUFF YOU NEED TO DO ....

    public static byte[] ReadToEnd(System.IO.Stream stream)
    {
        long originalPosition = 0;

        if (stream.CanSeek)
        {
            originalPosition = stream.Position;
            stream.Position = 0;
        }

        try
        {
            byte[] readBuffer = new byte[4096];

            int totalBytesRead = 0;
            int bytesRead;

            while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
            {
                totalBytesRead += bytesRead;

                if (totalBytesRead == readBuffer.Length)
                {
                    int nextByte = stream.ReadByte();
                    if (nextByte != -1)
                    {
                        byte[] temp = new byte[readBuffer.Length * 2];
                        Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                        Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                        readBuffer = temp;
                        totalBytesRead++;
                    }
                }
            }

            byte[] buffer = readBuffer;
            if (readBuffer.Length != totalBytesRead)
            {
                buffer = new byte[totalBytesRead];
                Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
            }
            return buffer;
        }
        finally
        {
            if (stream.CanSeek)
            {
                stream.Position = originalPosition;
            }
        }
    }

Hope this will help other people, because I couldn't find a direct answer on the internet!

Freeetje
  • 523
  • 8
  • 27
  • 1
    I know this is and old Q, but this will not preform very well. SP2013 has file.length but in 2010 you can do what is suggested above. – Steve Drake Feb 23 '16 at 09:25
0

Can't you just use the Stream property's length?

file.Size = fileInformation.Stream.Length;
Brian Dishaw
  • 5,767
  • 34
  • 49
  • 1
    Thank you for sending a reply. I tried fileInformation.Stream.Length to get stream length. but,this property throws System.NotSupportedException. Code which copies a stream from such a reason. mmm...A solution is not found by me yet. regards – user834964 Dec 07 '11 at 05:04