为什么下载的文件大于输入流?

时间:2019-03-04 21:00:32

标签: c# stream downloading

我正在编写C#方法来获取MemoryStream并将其作为文件下载到浏览器中。 我使用FileStream加载.xlsx文件并将其复制到MemoryStream

require(tidyverse)
#> Loading required package: tidyverse

diamonds %>% 
  filter(color == "E" | color == "J") %>% 
  filter(cut == "Good" | cut == "Premium") %>% 
  filter(price < 400) %>% 
  ggplot(aes(x = price, fill = cut)) +
  geom_histogram(bins = 10, position = "dodge") + 
  facet_wrap(~color)

然后我将docStream传递给OpenXML类

p <- last_plot() #this is important, because I want to insert this function after an existing plot
p$data #This is filtered, but it's not what we want because it isn't binned and so doesn't match the ggplot.
#> # A tibble: 41 x 10
#>    carat cut     color clarity depth table price     x     y     z
#>    <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#>  1  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
#>  2  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
#>  3  0.31 Good    J     SI2      63.3    58   335  4.34  4.35  2.75
#>  4  0.3  Good    J     SI1      64      55   339  4.25  4.28  2.73
#>  5  0.2  Premium E     SI2      60.2    62   345  3.79  3.75  2.27
#>  6  0.32 Premium E     I1       60.9    58   345  4.38  4.42  2.68
#>  7  0.3  Good    J     SI1      63.4    54   351  4.23  4.29  2.7 
#>  8  0.3  Good    J     SI1      63.8    56   351  4.23  4.26  2.71
#>  9  0.23 Good    E     VS2      61.8    63   357  3.88  3.89  2.4 
#> 10  0.25 Good    E     VS1      63.3    60   361  3.99  4.04  2.54
#> # … with 31 more rows

pgb_data <- ggplot_build(p)$data[[1]]


#This has the data, but doesn't tell us the label of the facet, or the label of the fill:
pgb_data %>% 
  select(x, y, count, group, PANEL)
#>           x y count group PANEL
#> 1  326.7778 1     1     2     1
#> 2  323.0000 1     1     1     1
#> 3  334.3333 0     0     2     1
#> 4  330.5556 0     0     1     1
#> 5  341.8889 0     0     2     1
#> 6  338.1111 0     0     1     1
#> 7  349.4444 2     2     2     1
#> 8  345.6667 0     0     1     1
#> 9  357.0000 0     0     2     1
#> 10 353.2222 1     1     1     1
#> 11 364.5556 0     0     2     1
#> 12 360.7778 1     1     1     1
#> 13 372.1111 4     4     2     1
#> 14 368.3333 2     2     1     1
#> 15 379.6667 0     0     2     1
#> 16 375.8889 2     2     1     1
#> 17 387.2222 2     2     2     1
#> 18 383.4444 0     0     1     1
#> 19 394.7778 1     1     2     1
#> 20 391.0000 0     0     1     1
#> 21 326.7778 0     0     2     2
#> 22 323.0000 0     0     1     2
#> 23 334.3333 0     0     2     2
#> 24 330.5556 1     1     1     2
#> 25 341.8889 0     0     2     2
#> 26 338.1111 1     1     1     2
#> 27 349.4444 0     0     2     2
#> 28 345.6667 2     2     1     2
#> 29 357.0000 0     0     2     2
#> 30 353.2222 0     0     1     2
#> 31 364.5556 2     2     2     2
#> 32 360.7778 1     1     1     2
#> 33 372.1111 2     2     2     2
#> 34 368.3333 2     2     1     2
#> 35 379.6667 2     2     2     2
#> 36 375.8889 1     1     1     2
#> 37 387.2222 0     0     2     2
#> 38 383.4444 0     0     1     2
#> 39 394.7778 5     5     2     2
#> 40 391.0000 5     5     1     2

#Here's an approximation what I'd like to get as output:

diamonds %>% 
  filter(color == "E" | color == "J") %>% 
  filter(cut == "Good" | cut == "Premium") %>% 
  filter(price < 400) %>% 
  mutate(price_bin = cut(price, breaks = 10)) %>% 
  count(cut, color, price_bin)
#> # A tibble: 20 x 4
#>    cut     color price_bin     n
#>    <ord>   <ord> <fct>     <int>
#>  1 Good    E     (326,333]     1
#>  2 Good    E     (353,360]     1
#>  3 Good    E     (360,367]     1
#>  4 Good    E     (367,374]     2
#>  5 Good    E     (374,380]     2
#>  6 Good    J     (333,340]     2
#>  7 Good    J     (346,353]     2
#>  8 Good    J     (360,367]     1
#>  9 Good    J     (367,374]     1
#> 10 Good    J     (374,380]     2
#> 11 Good    J     (387,394]     5
#> 12 Premium E     (326,333]     1
#> 13 Premium E     (340,346]     2
#> 14 Premium E     (367,374]     4
#> 15 Premium E     (380,387]     2
#> 16 Premium E     (387,394]     1
#> 17 Premium J     (360,367]     2
#> 18 Premium J     (367,374]     2
#> 19 Premium J     (374,380]     2
#> 20 Premium J     (387,394]     5

,并使用OpenXML类和方法更新内容。 最后,我将docStream传递给DownloadStream方法,但是下载的文件大于流的大小。

using (FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    docStream = new MemoryStream();
    fs.CopyTo(docStream);
}

我设置了一个断点,并验证了using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docStream, true)) public class Utility { public static void DownloadStream(MemoryStream inputStream, string filename) { byte[] bytes = inputStream.ToArray(); HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + filename); HttpContext.Current.Response.AddHeader("Content-Length", bytes.Length.ToString()); HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.BinaryWrite(bytes); } } 个字节。 我还确认了inputStream.Lentgh17112

当我检查下载文件(.xslx)时,它的大小为bytes.Length字节。

此外,当我打开文件时,我收到一条警告,提示文件可能已损坏,但Excel可以修复它。

1 个答案:

答案 0 :(得分:0)

我能够通过在SO中找到类似的问题来解决该问题。它与编码无关。

问题是我需要添加:

<ul class="pagination">
<li><a href="link">&lt;&lt;</a></li>
<li><a href="link">&lt;</a></li>
<li class="hidden-xs"><a href="link">1</a></li>
<li class="hidden-xs active"><a href="link">2</a></li>
<li class="hidden-xs"><a href="link">3</a></li>
<li class="hidden-xs"><a href="link">4</a></li>
<li class="hidden-xs"><a href="link">5</a></li>
<li><a href="link"> &gt;</a></li>
<li><a href="link"> &gt;&gt;</a></li>
</ul>

HttpContext.Current.Response.End(); 之后进入我的DownloadStream方法。

BinaryWrite