发送到API端点时如何读取文件

时间:2019-02-14 07:25:58

标签: c# .net file asp.net-web-api asp.net-web-api2

问题:我想知道在发送到终点时如何读取文件。

阅读多篇文章并做一些研究之后,我可以将文件发送到Amazon S3存储桶。以下是working code,但我不了解如何通过邮递员将文件发送到我的API,以及如何进行处理以及如何在代码中读取该文件。有人可以帮我解码此代码。

  

我已经在要理解的代码中添加了行号。

Line Number

1 [httppost]
2 public async Task<bool> Upload()
  {
    try
    {
3       var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
4       foreach (var content in filesReadToProvider.Contents)
        {
5           var stream = await content.ReadAsStreamAsync();
6           using (StreamReader sr = new StreamReader(stream))
            {
                string line = "";
7               while ((line = sr.ReadLine()) != null)
                {
8                   using (MemoryStream outputStream = new MemoryStream())
9                   using (StreamWriter sw = new StreamWriter(outputStream))
                    {
                        sw.WriteLine(line);
10                      sw.Flush();
                        PutRecordRequest putRecord = new PutRecordRequest();
                        putRecord.DeliveryStreamName = myStreamName;
                        Record record = new Record();
11                      outputStream.Position = 0;
                        record.Data = outputStream;
                        putRecord.Record = record;
                        try
                        {
                            await kinesisClient.PutRecordAsync(putRecord);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Failed to send record to Kinesis. Exception: {0}", ex.Message);
                        }
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
    }

    return true;
  }

P.S:我正在通过邮递员发送一个文件,以测试此端点的工作情况。

我对以上代码的理解。

Line Number 1:这是一个HTTPPOST请求,这意味着我发送的内容将在请求的正文中,而不在标头或URL中。由于我正在发送文件,因此文件内容将在请求的正文中发送。

Line Number 2: asyn,因此它将在单独的线程上运行,因此我的UI(如果有)将响应。

Line Number 3:我猜Request基本上是读取任何API Request正文内容的句柄,所以我正在使用Request.Content读取内容,
问题: ReadAsMultipartAsync是什么意思:它说:Reads all body parts within a MIME multipart message and produces a set of System.Net.Http.HttpContent instances as a result.?这是什么意思这是否意味着如果我的文件有10行,它正在读取所有10行,并以某种方式将其存储在内存中(以通俗的说法)?

Line Number 4:我猜filesReadToProvider.Contents还是我文件中所有这10行的句柄。这是否意味着如果我的文件中有 10行,此循环将运行 10次我认为我错了)。< / p>

Line Number 5: ReadAsStreamAsync表示:Serialize the HTTP content and return a stream that represents the content as an asynchronous operation.。这是否意味着它一次读取1行并对其进行序列化?但是为什么要序列化行?

LineNumber 6:由于有要处理的流,因此我要创建一个streamreader实例并将该流传递给它。 (用外行的话来说:我正在传递正在读取的一行文件)?

除此之外,我迷路了。此后,我完全感到困惑。什么是流?是我文件中的一行吗?

问题:请有人帮助我理解上面代码中的情况。我认为我不能直接将文件的行与流链接。请引导我。

2 个答案:

答案 0 :(得分:2)

第1行:设置响应HttpPost的方法

第2行:异步意味着执行任务(可以在单独的线程上,在这种情况下可以执行),然后在任务完成或失败时重新调用此方法。

第3行:多部分HTTP是经常用于发送文件What is http multipart request?

的标准

第4行:这是用户已发送的Multipart请求的不同内容。

第5行:以流的形式获取此部分的内容。流仅执行字节读取,并且不是非常用户友好。因此,第6行中的StreamReader。

第6行:创建一个StreamReader,它是一个帮助程序类,允许逐行处理Stream。

第7行:循环执行,将第一个行作为字符串,直到我们击到空值为止。

第8行:构造一个内存流。内存流是在内存中而不是从网络或磁盘中执行读/写操作的流。

第9行:在内存流周围使用StreamWriter。 StreamWriter是一个帮助程序类,它将使基于行的操作更加容易。

第10行:使用StreamWriter从第7行开始的循环中写入当前行。我们对其进行刷新,以使其内部包含整行。如果我们不这样做,可能不会包含所有内容。默认情况下,流将进行缓冲,这意味着它们将延迟其读/写操作,直到为性能优化添加了足够的数据为止。这会强制执行读/写操作。

第11行:如果我们不将MemoryStream的位置设置回0,则它将在插入行之后尝试读取。这会将其设置回该行的开头。 MemoryStream基本上是一个字节缓冲区,其中包含您所放内容以及当前的读/写位置信息。

答案 1 :(得分:0)

流是数据流,可以有许多不同的类型。 StreamReader将读入文件,并且需要一个流才能将其读入。您没有从文件传递一行,基本上是在打开文件并将其内容异步读取到流中。当实际数据太大而无法在写入之前一次全部读入内存时,人们有时会使用这样的流。

此代码使用内存流来缓冲从文件中读取的信息,并使用KinesisClient将其写出。我对KinesisClient并不是很熟悉,但是考虑到您说的代码有效,我会说它正在优雅地处理解析传递的流以写出信息。