Ftp以只读方式上传文件或以其他方式阻止覆盖

时间:2015-07-09 15:42:20

标签: c# ftp

我需要防止现有文件被覆盖(通过此代码,不关心其他ftp代码覆盖它),我认为一种方法可能是将它们上传为只读文件,任何能够做到这一点的人或其他建议?

这是我基于此msdn example的简单上传器:

public class FtpUploader
{
    private readonly string _root;

    public FtpUploader(string root)
    {
        _root = root;
        Credentials = new NetworkCredential("anonymous", "");
    }

    public NetworkCredential Credentials { get; set; }

    public async Task<bool> UploadAsync(string fileName, byte[] fileContents)
    {
        var doc = Path.Combine(_root, fileName);

        var request = (FtpWebRequest) WebRequest.Create(doc);
        request.Method = WebRequestMethods.Ftp.UploadFile;

        request.Credentials = Credentials;

        request.ContentLength = fileContents.Length;
        using (var requestStream = request.GetRequestStream())
        {
            await requestStream.WriteAsync(fileContents, 0, fileContents.Length);
        }

        using (var response = (FtpWebResponse) await request.GetResponseAsync())
        {
            Console.WriteLine("Upload File Complete, status {0}", response.StatusCode);
            return response.StatusCode == FtpStatusCode.ClosingData;
        }
    }
}

像这样使用:我希望文件不被覆盖并从上传返回false(或抛出一些异常)

byte[] fileContents = Encoding.UTF8.GetBytes("Hello world!");
var res1 = await new FtpUploader(root).UploadAsync("hello.txt", fileContents);

fileContents = Encoding.UTF8.GetBytes("Should not get set to this!");
var res2 = await new FtpUploader(root).UploadAsync("hello.txt", fileContents);

我已经尝试WebRequestMethods.Ftp.UploadFileWithUniqueName如果有第二步重命名/轻松移动会没问题吗?并且无法重命名/移动。

2 个答案:

答案 0 :(得分:1)

我认为您应该检查文件是否存在。

您可以查看此示例:Stackoverflow example

我希望这可以帮到你!

答案 1 :(得分:0)

我可以分两步上传和重命名。这解决了另一个问题;在完全上传之前,侦听器不得检测新文件。

但仍然对其他方法感兴趣。

public class FtpUploader
{
    private readonly string _root;

    public FtpUploader(string root)
    {
        _root = root;
        Credentials = new NetworkCredential("anonymous", "");
    }

    public NetworkCredential Credentials { get; set; }

    public async Task<bool> UploadAsync(string fileName, byte[] fileContents)
    {
        //var doc = Path.Combine(_root, fileName);

        var request = (FtpWebRequest) WebRequest.Create(_root);
        request.Method = WebRequestMethods.Ftp.UploadFileWithUniqueName;

        request.Credentials = Credentials;

        request.ContentLength = fileContents.Length;
        using (var requestStream = request.GetRequestStream())
        {
            await requestStream.WriteAsync(fileContents, 0, fileContents.Length);
        }

        using (var response = (FtpWebResponse) await request.GetResponseAsync())
        {
            Console.WriteLine("Upload File Complete, status {0}", response.StatusCode);
            Console.WriteLine(response.ResponseUri);

            if (response.StatusCode != FtpStatusCode.ClosingData) return false;

            try
            {
                return await Rename(response.ResponseUri, fileName);
            }
            catch (WebException)
            {
                return false;
            }
        }
    }

    private async Task<bool> Rename(Uri newUri, string newFileName)
    {
        var request = (FtpWebRequest) FtpWebRequest.Create(newUri);
        request.Proxy = null;
        request.Credentials = Credentials;

        request.Method = WebRequestMethods.Ftp.Rename;
        request.RenameTo = newFileName;
        using (var response = (FtpWebResponse) await request.GetResponseAsync())
        {
            Console.WriteLine("Rename File Complete, status {0}", response.StatusCode);
            Console.WriteLine(response.ResponseUri);

            return response.StatusCode == FtpStatusCode.FileActionOK;
        }
    }
}