C# 中的 Stream Empty 读取和上传 Excel 文件

Posted

技术标签:

【中文标题】C# 中的 Stream Empty 读取和上传 Excel 文件【英文标题】:Stream Empty in C# to Read and Upload Excel File 【发布时间】:2016-08-15 00:09:19 【问题描述】:

我在使用 Excel Data Reader 的 IExcelDataReader 读取 HttpPostedFileBase Excel 文件并结合 AWS SDK API 上传相同的 Excel 文件时遇到问题。进行验证以确定文件是应该上传还是仅在数据表中使用,如果验证通过,则始终上传 0 Kb 的空 Excel 文件。

我尝试过:在使用文件的 InputStream 之前关闭并处理 IExcelDataReader;创建一个新的流并上传;重置 InputStream 的位置;并检查此站点是否有类似问题。此外,在验证上传完整文档之前放置上传,但随后的 IExcelDataReader 会引发“无法使用已处置的对象”错误。

有谁知道如何重用文件InputStream?提前致谢!

//If save to bucket area is here, upload works, but later logic fails on disposed object

IExcelDataReader uploadReader;

switch (uploadExtension)

    case ".xls":
        uploadReader = ExcelReaderFactory.CreateBinaryReader(UploadedFile.InputStream);
        break;
    case ".xlsx":
        uploadReader = ExcelReaderFactory.CreateOpenXmlReader(UploadedFile.InputStream);
        break;
    default:
        uploadReader = ExcelReaderFactory.CreateBinaryReader(UploadedFile.InputStream);
        break;

DataSet excelUploadDataSet = uploadReader.AsDataSet();
var resultSheets = from DataTable sheet in excelUploadDataSet.Tables select sheet.TableName;
var excelSheets = resultSheets.ToList();
DataTable excelUpload = excelUploadDataSet.Tables[0];
int excelRows;

if ((string)excelSheets[0] != "Info")

    //Tried everything in the problem here, to no avail
    //Save to bucket area
    using (var client = new AmazonS3Client(Amazon.RegionEndpoint.USWest1))
    
        PutObjectRequest request = new PutObjectRequest
        
            BucketName = bucketLocation,
            Key = UploadedFile.FileName,
            InputStream = UploadedFile.InputStream
        ;
        PutObjectResponse response = client.PutObject(request);
    

else

    //Other logic using data table/IExcelDataReader

【问题讨论】:

【参考方案1】:

您有从UploadedFile.InputStream 读取的代码(因此将其搜索到末尾),然后您尝试将该流(位置设置到末尾,因此没有任何可读取的内容)传递给其他方法。由于PutObject 无法从流中读取任何内容并发送空数据。

可能的修复 - 将位置设置为 0(请参阅 Stream.Seek(0, SeekOrigin.Begin) or Position = 0),但请注意,在许多情况下流是不可搜索的(即在 ASP.Net 中上传的文件) - 在这种情况下,您需要读取流一次或复制它本地(即MemoryStream)读取多次。

【讨论】:

感谢阿列克谢的回复。我试图避免 MemoryStream,但在这种情况下我看不到任何解决方法。您是否看到了一种只读取一次 InputStream,但同时将其用于 Excel 数据读取器和 PutObject 的方法? @jle 我不知道。您可以尝试搜索“C# split stream”,也许有人提出解决方案(我也怀疑 - ***.com/questions/1055872/…)。 非常感谢。它正在使用 MemoryStream 工作,因此将围绕它进行编码。

以上是关于C# 中的 Stream Empty 读取和上传 Excel 文件的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的Stream流

C# 中的Stream流

将文件加载为字节数组,而不在内存中分配它 C#

C#应用配置信息保存和读取

C#流(stream)

通过ajax请求上传文件时读取文件大小