Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建文本文件并下载_C#_Asp.net_File_Download - Fatal编程技术网

C# 创建文本文件并下载

C# 创建文本文件并下载,c#,asp.net,file,download,C#,Asp.net,File,Download,我正在尝试写入内存中的文本文件,然后下载该文件,而不将该文件保存到硬盘。我正在使用StringWriter编写内容: StringWriter oStringWriter = new StringWriter(); oStringWriter.Write("This is the content"); 然后如何下载此文件 编辑: 正是这些答案的组合给了我答案。这是: StringWriter oStringWriter = new StringWriter(); oStringWriter.W

我正在尝试写入内存中的文本文件,然后下载该文件,而不将该文件保存到硬盘。我正在使用
StringWriter
编写内容:

StringWriter oStringWriter = new StringWriter();
oStringWriter.Write("This is the content");
然后如何下载此文件

编辑: 正是这些答案的组合给了我答案。这是:

StringWriter oStringWriter = new StringWriter();
oStringWriter.WriteLine("Line 1");
Response.ContentType = "text/plain";

Response.AddHeader("content-disposition", "attachment;filename=" + string.Format("members-{0}.csv",string.Format("{0:ddMMyyyy}",DateTime.Today)));
Response.Clear();

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8))
{
    writer.Write(oStringWriter.ToString());
}
Response.End();

这非常简单,答案可以在这篇Microsoft KB文章中看到:

基本上,您可以通过实现接口来创建一个HttpHandler。在
ProcessRequest
方法中,基本上只需将文本写入
context.Response
。您还需要添加
内容处置
http头:

context.Response.AddHeader("Content-Disposition", "attachment; filename=YourFileName.txt");
还要记住设置
内容类型

context.Response.ContentType = "text/plain";

您可以直接将数据写入响应流,而不是将数据存储在内存中然后发送到响应流:

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) {
  writer.Write("This is the content");
}

该示例使用UTF-8编码,如果您使用其他编码,则应更改该编码。

只是对其他答案的一小部分补充。在下载的最后,我执行:

context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
我了解到,否则,下载有时无法成功完成

还要注意的是,
Response.End
抛出了一个
ThreadAbortException
,您可以使用
CompleteRequest
方法来避免该异常。

这为我解决了:

        MemoryStream ms = new MemoryStream();
        TextWriter tw = new StreamWriter(ms);
        tw.WriteLine("Line 1");
        tw.WriteLine("Line 2");
        tw.WriteLine("Line 3");
        tw.Flush();
        byte[] bytes = ms.ToArray();
        ms.Close();

        Response.Clear();
        Response.ContentType = "application/force-download";
        Response.AddHeader("content-disposition", "attachment;    filename=file.txt");
        Response.BinaryWrite(bytes);
        Response.End();     

我对此有很多问题。Finnaly找到了一个似乎每次都有效的解决方案

在大多数情况下,用户将单击按钮进行下载。此时,最好将页面重定向回同一位置。在url中添加一个可以抓取和读取的参数

示例(www.somewhere.com/mypage.aspx?print=stuff)


受保护的无效页面加载(对象发送方、事件参数e){
如果(请求[“打印”]=“内容”){print(“我的测试内容”);}
}
/*或传递字节[]内容*/
私有无效打印(字符串内容){
Response.ContentType=“text/plain”;
AddHeader(“内容处置”,“附件;文件名=myFile.txt”);
//响应.二进制写入(内容);
回答。写(内容);
Response.Flush();
Response.End();
}
受保护的无效btn_单击(对象发送方,事件参数e){
//如果使用异步,回发会给您带来麻烦。
//调用Response.End()时将给出错误。
重定向(Request.Url+“?print=queue”);
}

对@Vinicious answer的扩展

我有可能包含逗号的数据。常见的解决方案是通过将该数据段括在引号中来转义,同时确保也转义可能是数据一部分的引号

在编写CSV时,我遇到了一个难题和一个警告:如果在逗号后面加空格,excel将不喜欢您

下面将导致excel出现问题。在excel中,第一个引号将成为数据的一部分,因此不会在嵌入的逗号处分开。空间不好

 tw.Write(Environment.NewLine + string.Format("{0:#.000000}, {1:#.000000}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC)));

这并不能真正回答问题。。。higgsy指定不应将文件写入硬盘。您好,确切地说,不应将文件写入硬盘。您好,Guffa-然后如何获取要下载的响应流?@higgsy:您在标题中添加内容配置和内容类型的说明,以便浏览器知道它是什么。Klaus Byskow Hoffman在他的回答中有一些例子,但是您不必使用HTTP处理程序来返回响应,它也可以与常规页面一起工作。您还应该在内容类型中指定编码,例如
text/plain;charset=utf-8
。事实上,当我使用您添加的行时,生成的文件包含我在流中编写的文本以及呈现的html代码,因此我必须返回代码,只需放入“Response.End”行,它就可以正常工作了!通常,我只通过单独的ASHX处理程序提供下载,而不是在ASPX页面中。
protected void btnDownload_Click(object sender, EventArgs e)
{
    MemoryStream ms = new MemoryStream();
    TextWriter tw = new StreamWriter(ms, System.Text.Encoding.UTF8);
    var structures = KAWSLib.BusinessLayer.Structure.GetStructuresInService();
    // *** comma delimited
    tw.Write("Latitude, Longitude, CountySerial, StructureType, Orientation, District, RoutePre, RouteNo, LocationDesc");
    foreach (var s in structures)
    {
        tw.Write(Environment.NewLine + string.Format("{0:#.000000},{1:#.000000},{2},{3},{4},{5},{6},{7},{8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC)));
    }
    tw.Flush();
    byte[] bytes = ms.ToArray();
    ms.Close();

    Response.Clear();
    Response.ContentType = "application/force-download";
    Response.AddHeader("content-disposition", "attachment;    filename=" + string.Format("kaws-structures-{0:yyyy.MM.dd}.csv", DateTime.Today));
    Response.BinaryWrite(bytes);
    Response.End();
}

string EscapeIfNeeded(string s)
{
    if (s.Contains(","))
    {
        return "\"" + s.Replace("\"", "\"\"") + "\"";
    }
    else
    {
        return s;
    }
}
 tw.Write(Environment.NewLine + string.Format("{0:#.000000}, {1:#.000000}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC)));