programing

URL에서 파일 다운로드/스트리밍 - asp.net

javamemo 2023. 6. 24. 08:43
반응형

URL에서 파일 다운로드/스트리밍 - asp.net

브라우저에 저장 메시지가 표시되도록 파일을 스트리밍해야 합니다.문제는 파일이 있는 디렉터리가 가상으로 매핑되어 있어서 서버를 사용할 수 없습니다.MapPath를 통해 실제 위치를 확인할 수 있습니다.디렉터리가 웹 사이트와 같은 위치(또는 라이브 박스의 실제 서버)에 있지 않습니다.

다음과 같은 것을 원하지만 서버 파일 경로가 아닌 웹 URL을 전달할 수 있습니다.

구성 기본 경로에서 파일 경로를 구축한 다음 나머지 경로에 추가해야 할 수도 있지만, 이러한 방식으로 대신할 수 있기를 바랍니다.

var filePath = Server.MapPath(DOCUMENT_PATH);

if (!File.Exists(filePath))
    return;

var fileInfo = new System.IO.FileInfo(filePath);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath));
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(filePath);
Response.End();

HttpWebRequest를 사용하여 파일을 가져와 클라이언트에 다시 스트리밍할 수 있습니다.이렇게 하면 url과 함께 파일을 가져올 수 있습니다.내가 찾은 이것의 예는 (그러나 어디에 신용을 부여해야 하는지 기억할 수 없습니다).

    //Create a stream for the file
    Stream stream = null;

    //This controls how many bytes to read at a time and send to the client
    int bytesToRead = 10000;

    // Buffer to read bytes in chunk size specified above
    byte[] buffer = new Byte[bytesToRead];

    // The number of bytes read
    try
    {
      //Create a WebRequest to get the file
      HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);

      //Create a response for this request
      HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();

      if (fileReq.ContentLength > 0)
        fileResp.ContentLength = fileReq.ContentLength;

        //Get the Stream returned from the response
        stream = fileResp.GetResponseStream();

        // prepare the response to the client. resp is the client Response
        var resp = HttpContext.Current.Response;

        //Indicate the type of data being sent
        resp.ContentType = MediaTypeNames.Application.Octet;
    
        //Name the file 
        resp.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());
    
        int length;
        do
        {
            // Verify that the client is connected.
            if (resp.IsClientConnected)
            {
                // Read data into the buffer.
                length = stream.Read(buffer, 0, bytesToRead);

                // and write it out to the response's output stream
                resp.OutputStream.Write(buffer, 0, length);

                // Flush the data
                resp.Flush();

                //Clear the buffer
                buffer = new Byte[bytesToRead];
            }
            else
            {
                // cancel the download if client has disconnected
                length = -1;
            }
        } while (length > 0); //Repeat until no data is read
    }
    finally
    {
        if (stream != null)
        {
            //Close the input stream
            stream.Close();
        }
    }

url을 바이트로 다운로드하고 바이트를 스트림으로 변환:

using (var client = new WebClient())
{
    var content = client.DownloadData(url);
    using (var stream = new MemoryStream(content))
    {
        ...
    }
}   

저는 이것을 꽤 많이 하고 더 간단한 답을 추가할 수 있다고 생각했습니다.저는 이곳에서 간단한 수업으로 설정했지만, 제가 팔로우하고 있는 회사의 재무 데이터를 수집하기 위해 매일 저녁에 운영하고 있습니다.

class WebPage
{
    public static string Get(string uri)
    {
        string results = "N/A";

        try
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            StreamReader sr = new StreamReader(resp.GetResponseStream());
            results = sr.ReadToEnd();
            sr.Close();
        }
        catch (Exception ex)
        {
            results = ex.Message;
        }
        return results;
    }
}

이 경우 URL을 전달하면 페이지가 HTML로 반환됩니다.스트림에서 다른 작업을 수행하려면 이 작업을 쉽게 변경할 수 있습니다.

다음과 같이 사용합니다.

string page = WebPage.Get("http://finance.yahoo.com/q?s=yhoo");

2년 후, 달라스의 답변을 사용했지만, 저는 그것을 바꿔야 했습니다.HttpWebRequest로.FileWebRequest직접 파일에 링크하고 있었기 때문입니다.모든 곳에서 이런 경우인지는 모르겠지만, 저는 그것을 추가하기로 결심했습니다.또한, 저는 제거했습니다.

var resp = Http.Current.Resonse

그리고 방금 사용했습니다.Http.Current.Response어디서나 제자리에resp참조되었습니다.

@Dallas의 답변의 .NET Core 버전을 찾고 있다면 아래를 사용하십시오.

        Stream stream = null;

        //This controls how many bytes to read at a time and send to the client
        int bytesToRead = 10000;

        // Buffer to read bytes in chunk size specified above
        byte[] buffer = new Byte[bytesToRead];

        // The number of bytes read
        try
        {
            //Create a WebRequest to get the file
            HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(@"file url");

            //Create a response for this request
            HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();

            if (fileReq.ContentLength > 0)
                fileResp.ContentLength = fileReq.ContentLength;

            //Get the Stream returned from the response
            stream = fileResp.GetResponseStream();

            // prepare the response to the client. resp is the client Response
            var resp = HttpContext.Response;

            //Indicate the type of data being sent
            resp.ContentType = "application/octet-stream";

            //Name the file 
            resp.Headers.Add("Content-Disposition", "attachment; filename=test.zip");
            resp.Headers.Add("Content-Length", fileResp.ContentLength.ToString());

            int length;
            do
            {
                // Verify that the client is connected.
                if (!HttpContext.RequestAborted.IsCancellationRequested)
                {
                    // Read data into the buffer.
                    length = stream.Read(buffer, 0, bytesToRead);

                    // and write it out to the response's output stream
                    resp.Body.Write(buffer, 0, length);


                    //Clear the buffer
                    buffer = new Byte[bytesToRead];
                }
                else
                {
                    // cancel the download if client has disconnected
                    length = -1;
                }
            } while (length > 0); //Repeat until no data is read
        }
        finally
        {
            if (stream != null)
            {
                //Close the input stream
                stream.Close();
            }
        }

저는 그렇게 하는 가장 간단한 방법을 주장할 것입니다.Net Core는 다음과 같습니다.

using (MemoryStream ms = new MemoryStream())
    using (HttpClient client = new HttpClient())
    {
      client.GetStreamAsync(url).Result.CopyTo(ms);
      // use ms in what you want
    }
  }

이제 파일이 ms 내부의 스트림으로 다운로드되었습니다.

다음과 같은 IIS 경로 접두사를 사용하여 DirectoryEntry 클래스를 사용해 볼 수 있습니다.

using(DirectoryEntry de = new DirectoryEntry("IIS://Localhost/w3svc/1/root" + DOCUMENT_PATH))
{
    filePath = de.Properties["Path"].Value;
}

if (!File.Exists(filePath))
        return;

var fileInfo = new System.IO.FileInfo(filePath);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath));
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(filePath);
Response.End();

WAF 정책 없이 Citrix Netscaler에서 로드 밸런서를 사용할 경우 Dallas에서 수락한 솔루션이 효과를 발휘했습니다.

파일 다운로드는 현재 시나리오(콘텐츠 길이가 올바르지 않음)가 RFC 위반이고 AppFW가 연결을 재설정하는 경우 Netscaler의 LB를 통해 작동하지 않습니다. 이는 WAF 정책이 연결되지 않은 경우에는 발생하지 않습니다.

그래서 부족했던 것은:

대답.끝();

참고 항목:asp.net 에서 PDF 파일을 스트리밍하려고 하면 "filename file"이 생성됩니다.

사용자 기본 설정을 무시하는 것에 대해서도 동의하지 않지만, 다음은 제가 이 .net6을 수행한 방법입니다.

에 합니다.Startup.Configure기본적으로 PDF 컨텐츠 유형을 변경하고 다운로드 시 컨텐츠 처리를 추가합니다.대상 특정 파일 등만 추가로 세분화할 수 있습니다.

var extensionProvider = new FileExtensionContentTypeProvider();
extensionProvider.Mappings[".pdf"] = "application/octet-stream";

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = extensionProvider,
    OnPrepareResponse = response =>
    {
        if (response.File.Name.EndsWith(".pdf", StringComparison.InvariantCultureIgnoreCase))
        {
            response.Context.Response.Headers.Remove("content-disposition");
            response.Context.Response.Headers.Add("content-disposition","attachment; filename=\"" + response.File.Name + "\"");
        }
    }
}); 

언급URL : https://stackoverflow.com/questions/5596747/download-stream-file-from-url-asp-net

반응형