如何从Microsoft.SharePoint.Client.File对象中获取文件大小?

6
我正在寻找一种好的方法来从Microsoft.SharePoint.Client.File对象中获取文件大小。 Client对象没有Length成员。
我尝试了这个:
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;
    }
}

通过使用MemoryStream, 我可以获得长度,但这会影响性能。因为这个文件不属于文档库,它是一个附件,所以我不能使用ListItemAllFields将其转换为一个ListItem对象。如果我能够将其转换为ListItem对象,就可以使用ListItem["File_x0020_Size"]来获取它的大小。
如何使用C#获取SharePoint中Client对象的文件大小?

有人对这个问题有好的想法吗? - user834964
3个回答

6

加载File_x0020_Size字段信息以获取它。

当我想要列出Sharepoint 2010文件夹中所有文件时,我会这样做:

//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 显然是您发起的 ClientContext

这里有一个扩展列表,包含所有Sharepoint内部字段的参考


0

你不能直接使用Stream属性的长度吗?

file.Size = fileInformation.Stream.Length;

1
感谢您的回复。我尝试使用fileInformation.Stream.Length获取流长度,但是该属性会抛出System.NotSupportedException异常。因此,我无法从中复制流。目前我还没有找到解决方案。谢谢。 - user834964

0

我不知道这个问题是否已经解决,但对于那些正在寻找答案的人(就像我一样):

...获取SP.FILE的代码...

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

...做你需要做的其他事情....

    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;
            }
        }
    }

希望这能够帮助到其他人,因为我在互联网上找不到直接的答案!

1
我知道这是一个老问题,但这种方法的性能不是很好。SP2013有file.length属性,但在2010中,您可以执行上述建议。 - Steve Drake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接