首页 > 解决方案 > 如何正确处理临时文件?

问题描述

问题:我有一个 web api,它公开了一个方法UploadFile,它将一个文件从客户端上传到服务器的特定目录。处理请求并进行上传的代码如下:

var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);

var reader = new MultipartReader(boundary, HttpContext.Request.Body);

try
{
    // Read the form data.
    var section = await reader.ReadNextSectionAsync();

    // This illustrates how to get the file names.
    while (section != null)
    {
        var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);
        if (hasContentDispositionHeader)
        {

            if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
            {
                targetFilePath = Path.Combine(root, contentDisposition.FileName.ToString());
                using (var targetStream = System.IO.File.Create(targetFilePath))
                {
                    await section.Body.CopyToAsync(targetStream);

                    //_logger.LogInformation($"Copied the uploaded file '{targetFilePath}'");
                }
            }

我总是使用以下语句调用此方法:

bool res = await importClient.UploadFileAsync(filePath);

UploadFileAsync(在客户端)以这种方式构建请求:

var requestContent = new MultipartFormDataContent();
var array = File.ReadAllBytes(filePath);
var fileContent = new ByteArrayContent(array);
fileContent.Headers.ContentType =  MediaTypeHeaderValue.Parse("application/octet-stream");
requestContent.Add(fileContent, "file", Path.GetFileName(filePath));

如您所见,此方法需要一个文件名/路径才能工作,这意味着该文件必须“存在”于客户端计算机的某个位置。到目前为止,我一直使用这种方法没有任何问题。我有一个非常具体的情况,我需要在服务器上上传用户不想保存在他的客户端上的东西。

可能的解决方案:

我对这些主题缺乏经验,所以我不确定哪种解决方案最适合这种情况

我的要求是我需要 100% 确保文件在上传完成后被删除,并且我希望解决方案是“异步友好的”,即我需要整个过程继续没有问题。

编辑:我看到了一些混乱。我的问题不是如何处理服务器上的文件。那部分不是问题。我需要在客户端处理“临时”文件。

标签: c#

解决方案


一旦你在磁盘上写了一些东西,你就不能 100% 地删除它。此外,即使您删除了文件,也不能确定该文件无法恢复。

所以你要问我为什么要删除文件。如果它包含一些秘密,请将其保存在内存中。如果您无法将文件放入内存,请将其加密写入磁盘并仅将密钥保留在内存中。

如果你放松 100% 到 99%,我会去创建一个文件Path.GetTempFileName并在 finally 块中删除它。

如果 99% 还不够,但 99.98% 足够,我会将创建的临时文件的名称存储在持久存储中,并定期检查它们是否被删除。


推荐阅读