在SharePoint中上传大型文件.使用.NET上传后,文件正在损坏



在将文件上传到共享点站点时,文件正在损坏。我已经发布了下面的代码。提前致谢。我使用的是在线共享点。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();
            }
        }
    }
       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();
            }
        }
    }
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%WwwrootWssVirtualDirectories<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:windowssystem32inetsrv' 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
"12TEMPLATELAYOUTS" folder 
Open the 'Web.config' file from the 'C:Program FilesCommon FilesMicrosoft SharedWeb server extensions12TEMPLATELAYOUTS' 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:InetpubwwwrootwssVirtualDirectories' folder and modify it as follows 
Existing line:             <httpRuntime maxRequestLength="51200" />            
Replacement line:     <httpRuntime executionTimeout="999999" maxRequestLength="51200" />            
"12CONFIG" 
Open the web.config located at "C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12CONFIG" 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)      

最新更新