流不支持查找操作,使用流。

4
使用 C# ASP.net 4.5、Nopcommerce CMS、MVC 4 和 Visual Studio 2012。
这似乎是人们经常遇到的问题,我在“谷歌”上搜索了一下,但还没有找到符合我的需求的解决方案。
请注意,这不是我的代码,我被要求修复此问题(我只具备有限的文件 I/O 知识,仅限于基础知识)。
错误堆栈跟踪如下:
"   at System.Net.ConnectStream.set_Position(Int64 value)\r\n   at   Hroc.Plugin.Core.CsvProductManagement.Services.CsvReader.Initialise(Stream stream, Encoding encoding)\r\n   at Hroc.Plugin.Core.CsvProductManagement.Services.CsvReader..ctor(Stream stream)\r\n   at Hroc.Plugin.Core.CsvProductManagement.Services.ImportService.ImportStoreProductsFromCsv(Stream stream, Int32 storeContext, Int32 vendorId, Boolean deleteUnmatched)\r\n   at Hroc.Plugin.Core.CsvProductManagement.Services.StaticImportFile.GetStoreProductImportMessages(Stream stream, Int32 storeContext, Int32 vendorId, Boolean deleteUnmatched)\r\n   at Hroc.Plugin.Core.CsvProductManagement.Tasks.ImportFilesTask.Execute()\r\n   at Nop.Services.Tasks.Task.Execute(Boolean throwException) in c:\\Users\\stevesmith\\Documents\\GitHub\\Store\\Libraries\\Nop.Services\\Tasks\\Task.cs:line 83"

现在进入代码部分,我会尽量保持简短(不过它是MVC的,所以要准备101种不同的方法...)

public void Execute() {
        if (_importTaskSettings.Enabled) {
            var response = HttpWebRequest.Create(_importTaskSettings.ImportFileUrl).GetResponse();
            
            if (response != null)
            {
                using (var stream = response.GetResponseStream())
                {
                    var messages = StaticImportFile.GetStoreProductImportMessages(stream, 0, 1, true); //error occurs here
                    _logger.Information(string.Format("Import Store products file task complete. Messages: {0}", string.Join(", ", messages))); 
                }
            }
            else {
                //_logger.Information('import was called but is null');
            }
        }
    }

这个方法在后台任务中使用定时器,用于调试目的,目前设置为30秒。

public virtual IList<string> ImportStoreProductsFromCsv(Stream stream, int storeContext = 0, int vendorId = 0, bool deleteUnmatched = false) {
        // Store always uploads against all stores
        storeContext = 0;

        using (var s = new CsvReader(stream)) {
            // read CSV file stream into List
.....etc etc
}

当然,错误位于使用系统CsvReader时。

 /// <summary>
    /// Initialises the reader to work from an existing stream
    /// </summary>
    /// <param name="stream">Stream</param>
    public CsvReader(Stream stream) {
        _type = Type.Stream;
        Initialise(stream, Encoding.Default);
    }

好的,上面是一个深植于nop commerce和自定义插件中的实际代码片段。然而,我相信故障在流程处理中的某个地方。

这里的目的是,服务器上存储的一个文件每小时都会更新。管理员无法访问该文件,但产品也需要更新。因此,运行一个任务来查找路径,创建一个流,并使用nop commerce的方法将文件数据输入到商店的网站中。

现在阅读了很多论坛,大多数人都说是在尝试寻找开放流的同时尝试写入的行为造成的?(不确定是否表达正确)从这个过程中,实际的流程并没有试图在流中寻找?

我希望我的错误是一些小问题,我不想创建一个新的插件并扩展Nop的功能。

如果您需要更多信息,请告诉我,我会更新这个问题。

1个回答

18
ResponseStream确实不支持Seek操作。您可以通过查看CanSeek属性来验证此操作。
简单的解决方案:
using (var stream1 = response.GetResponseStream())
using (var stream2 = new MemoryStream())
{
    stream1.CopyTo(stream2);
    var messages = StaticImportFile.GetStoreProductImportMessages(stream2, 0, 1, true);
}

但是这对于非常大的流(例如100 MB及以上)效果不佳。


啊!太棒了,我没想到可以将其复制到另一个流中并使用它。简单明了的解决方案。你得到了 +1 和已接受的答案! - lemunk

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