在sharepoint中上传大文件。使用.net上传文件后,文件已损坏

时间:2018-02-21 16:40:59

标签: c# .net sharepoint-2010

在共享点网站上传文件时,文件已损坏。我已经发布了以下代码。提前致谢。我正在使用Share point Online.CSOM-版本16.1.7317。此代码用于上传大于25mb的文件,文件分为3个部分。此处使用的单个块大小为8 MB。 切片上传应该是同步调用。我们不能让多个线程同时上传块。上传的顺序非常重要。 如果块的上载失败,SharePoint将锁定该文件15分钟,等待上载恢复。如果在给定的时间范围内没有建立连接,则取消整个上载。还要记住,当前的锁定间隔可以在不事先通知的情况下进行更改。

public void Upload()
    {
        ClientResult<long> bytesUploaded = null;

        FileStream fs = null;
        try
        {

            int blockSize = 8000000; // 8 MB

            string uniqueFileName = String.Empty;
            long fileSize;
            Microsoft.SharePoint.Client.File uploadFile = null;
            Guid uploadId = Guid.NewGuid();

            string userName = "your Username";
            string pwd = "your password";

            string fileName = Convert.ToString(FileUpload1.PostedFile.FileName);


            using (ClientContext ctx = new ClientContext("site url"))
            {

                SecureString passWord = new SecureString();
                foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);

                ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);
                List docs = ctx.Web.Lists.GetByTitle("Documents");
                ctx.Load(docs.RootFolder, p => p.ServerRelativeUrl);// ServerUrl provide you with the same Server relative path of a document inside a document library

                // Use large file upload approach


                fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                fileSize = fs.Length;
                uniqueFileName = System.IO.Path.GetFileName(fs.Name);

                using (BinaryReader br = new BinaryReader(fs))
                {
                    byte[] buffer = new byte[blockSize];
                    byte[] lastBuffer = null;
                    long fileoffset = 0;
                    long totalBytesRead = 0;
                    int bytesRead;
                    bool first = true;
                    bool last = false;

                    // Read data from filesystem in blocks
                    while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        totalBytesRead = totalBytesRead + bytesRead;

                        // We've reached the end of the file
                        if (totalBytesRead <= fileSize)
                        {
                            last = true;
                            // Copy to a new buffer that has the correct size
                            lastBuffer = new byte[bytesRead];
                            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
                        }

                        if (first)
                        {
                            using (MemoryStream contentStream = new MemoryStream())
                            {
                                // Add an empty file.
                                FileCreationInformation fileInfo = new FileCreationInformation();
                                fileInfo.ContentStream = contentStream;
                                fileInfo.Url = uniqueFileName;
                                fileInfo.Overwrite = true;
                                uploadFile = docs.RootFolder.Files.Add(fileInfo);

                                // Start upload by uploading the first slice.
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Call the start upload method on the first slice
                                    bytesUploaded = uploadFile.StartUpload(uploadId, s);
                                    ctx.ExecuteQuery();
                                    // fileoffset is the pointer where the next slice will be added
                                    fileoffset = bytesUploaded.Value;
                                }

                                // we can only start the upload once
                                first = false;
                            }
                        }
                        else
                        {
                            // Get a reference to our file
                            uploadFile = ctx.Web.GetFileByServerRelativeUrl(docs.RootFolder.ServerRelativeUrl + System.IO.Path.AltDirectorySeparatorChar + uniqueFileName);

                            if (last)
                            {
                                // Is this the last slice of data?
                                using (MemoryStream s = new MemoryStream(lastBuffer))
                                {
                                    // End sliced upload by calling FinishUpload
                                    uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();

                                    // return the file object for the uploaded file
                                  //return uploadFile;
                                }
                            }
                            else
                            {
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Continue sliced upload
                                    bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();
                                    // update fileoffset for the next slice
                                    fileoffset = bytesUploaded.Value;
                                }
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            if (fs != null)
            {
                fs.Dispose();

            }
        }
    }

2 个答案:

答案 0 :(得分:0)

       public Microsoft.Sharepoint.Client.File Upload()
    {
        ClientResult<long> bytesUploaded = null;

        FileStream fs = null;
        try
        {

            int blockSize = 8000000; // 8 MB

            string uniqueFileName = String.Empty;
            long fileSize;
            Microsoft.SharePoint.Client.File uploadFile = null;
            Guid uploadId = Guid.NewGuid();

            string userName = "your Username";
            string pwd = "your password";

            string fileName = Convert.ToString(FileUpload1.PostedFile.FileName);


            using (ClientContext ctx = new ClientContext("site url"))
            {

                SecureString passWord = new SecureString();
                foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);

                ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);
                List docs = ctx.Web.Lists.GetByTitle("Documents");
                ctx.Load(docs.RootFolder, p => p.ServerRelativeUrl);// ServerUrl provide you with the same Server relative path of a document inside a document library

                // Use large file upload approach


                fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                fileSize = fs.Length;


 fileSize = fs.Length;
                    if (fileSize <= blockSize)
                    {
                        blockSize = Convert.ToInt32(fileSize) - 1;//the file size should be less for the if condition with last slice to run.
                    }
                uniqueFileName = System.IO.Path.GetFileName(fs.Name);

                using (BinaryReader br = new BinaryReader(fs))
                {
                    byte[] buffer = new byte[blockSize];
                    byte[] lastBuffer = null;
                    long fileoffset = 0;
                    long totalBytesRead = 0;
                    int bytesRead;
                    bool first = true;
                    bool last = false;

                    // Read data from filesystem in blocks
                    while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        totalBytesRead = totalBytesRead + bytesRead;

                        // We've reached the end of the file
                        if (totalBytesRead <= fileSize)
                        {
                            last = true;
                            // Copy to a new buffer that has the correct size
                            lastBuffer = new byte[bytesRead];
                            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
                        }

                        if (first)
                        {
                            using (MemoryStream contentStream = new MemoryStream())
                            {
                                // Add an empty file.
                                FileCreationInformation fileInfo = new FileCreationInformation();
                                fileInfo.ContentStream = contentStream;
                                fileInfo.Url = uniqueFileName;
                                fileInfo.Overwrite = true;
                                uploadFile = docs.RootFolder.Files.Add(fileInfo);

                                // Start upload by uploading the first slice.
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Call the start upload method on the first slice
                                    bytesUploaded = uploadFile.StartUpload(uploadId, s);
                                    ctx.ExecuteQuery();
                                    // fileoffset is the pointer where the next slice will be added
                                    fileoffset = bytesUploaded.Value;
                                }

                                // we can only start the upload once
                                first = false;
                            }
                        }
                        else
                        {
                            // Get a reference to our file
                            uploadFile = ctx.Web.GetFileByServerRelativeUrl(docs.RootFolder.ServerRelativeUrl + System.IO.Path.AltDirectorySeparatorChar + uniqueFileName);

                            if (last==true && totalBytesRead >= fileSize)
                            {
                                // Is this the last slice of data?
                                using (MemoryStream s = new MemoryStream(lastBuffer))
                                {
                                    // End sliced upload by calling FinishUpload
                                    uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();

                                    // return the file object for the uploaded file
                                  return uploadFile;
                                }
                            }
                            else
                            {
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Continue sliced upload
                                    bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();
                                    // update fileoffset for the next slice
                                    fileoffset = bytesUploaded.Value;
                                }
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            if (fs != null)
            {
                fs.Dispose();

            }
        }
    }

答案 1 :(得分:0)

Increase the Maximum Upload Size for the Web Application from Central Administration site

Browse to Central Administration site and click on Application Management
Click on 'Web Application General Settings' under 'SharePoint Web Application Management ' and choose the appropriate web application
Modify the value for 'Maximum Upload Size' property to specify the maximum size which is allowed for a single upload to any site under the web application. 
Note: You can choose multiple files and folders to be uploaded provided no single file or the collective size goes beyond 2 GB
A value of '1000' would set the max upload size to 1 GB. The maximum upload size cannot be increased beyond '2000' (2 Gb)
The default file size for upload is 50 Mb in IIS 6.0) and 28 Mb for IIS 7.0.


Increase the connection time-out setting in IIS 

By default, the IIS connection time-out setting is 120 seconds (2 minutes). Follow these steps to increase the connection time-out setting: 
In IIS manager, expand the 'Sites' node and select the SharePoint site
Click 'Advanced Settings' from the actions pane OR right-click the SharePoint site, Manage Web site and click 'Advanced Settings'
Increase the 'Connection time-out' value (seconds); under 'Connection limits' from the 'Advanced Settings' dialog box to avoid IIS time-outs when large files are being uploaded
You can specify the time-out value based on file size and the time taken for the file to be uploaded
You can also select the SharePoint site in IIS and click on the 'Limits' link in the actions pane.    

Increase the maximum upload size in the web.config file of web application 

The maxAllowedContentLength property specifies the maximum length of content in a request in bytes and it needs to be set on a Windows Server 2008 computer that has IIS 7.0-only installations.

To change the value of the property via web.config, do the following:

Open the web.config file of a web application located in %Inetpub%\Wwwroot\Wss\VirtualDirectories\<Virtual Directory> folder and add the following code at the bottom, just before the close out of the <configuration> section of the Web.config file

            <Configuration>
            ..
            ..
            <system.webServer>
                <Security>
                        <RequestFiltering> 
                                   <requestLimits maxAllowedContentLength”52428800’/> 
                        </requestFiltering>
                </security>
            </system.webServer>
            </configuration>

 This sets the value of the maxAllowedContentLength property to 52428800 (in bytes) for the web application only.

 To change the value of the property via command-line, do the following:   

Open command prompt and go to 'C:\windows\system32\inetsrv' directory
Run the below command:         

Appcmd set config /section:requestfiltering /requestlimits.maxallowedcontentlength:unit 

Where the variable requestlimits.maxallowedcontentlength unit specifies the maximum length of content (in bytes). For example, to specify 2000000000 as the maximum length of content, type the following at the command prompt, and then press ENTER:

Appcmd set config /section:requestfiltering /requestlimits.maxallowedcontentlength:2000000000      


Increase the default chunk size for large files

The large-file-chunk-size property sets the amount of data that can be read from server running SQL Server at one time. Points to remember:             
If you have a file that is greater than your chunk size (such as 100 MB when the chunk size is set to 5 MB), the file would be read in 20 chunks (100 / 5).
The chunk size is not related to the maximum upload file size.
The chunk size simply specifies the amount of data that can be read from a file at one time. By default, the large-file-chunk-size property is set to 5 MB.
Be aware that if you set the chunk size too high, the files might use a high amount of memory of the web front-end.
In order to set the large–file–chunk–size property, we need to use the command line. This property is configured at a server or server farm level, and cannot be configured for an individual web application. To set this property, use the following syntax:

Stsadm.exe –o setproperty –pn large–file–chunk–size –pv <size in bytes>

Add the ExecutionTimeout Value in the web.config
"12\TEMPLATE\LAYOUTS" folder 

Open the 'Web.config' file from the 'C:\Program Files\Common Files\Microsoft Shared\Web server extensions\12\TEMPLATE\LAYOUTS' directory. Add the executionTimeout value that you want. For example, replace the value as follows 

Existing code 

<location path="upload.aspx"> 
    <system.web> 
        <httpRuntime maxRequestLength="2097151" /> 
    </system.web> 
</location>    

Replacement Code 

<location path="upload.aspx"> 
    <system.web> 
        <httpRuntime executionTimeout="999999" maxRequestLength="2097151" /> 
    </system.web> 
</location>  

Web App 

Open the web.config file located at 'C:\Inetpub\wwwroot\wss\VirtualDirectories\' folder and modify it as follows 

Existing line:             <httpRuntime maxRequestLength="51200" />            
Replacement line:     <httpRuntime executionTimeout="999999" maxRequestLength="51200" />            

"12\CONFIG" 

Open the web.config located at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG" and modify the 'maxRequestLength' property which by default should be the following:

 <httpRuntime maxRequestLength="51200"/>    

Change the value to match the other web.configs          


Save the file and perform an ' IISreset /noforce'.

Large file support limitations

The following features do not support files larger than 50 MB 

Virus checking.
Picture libraries.
Streaming files.
Client-side restoration of smigrate backup files (limited to 2 GB). The manifest files for an smigrate backup cannot be larger than 2 GB.
Site templates (limit of 10 MB per site template, including content)