2

目前我这样做

try
{
    cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);

}
catch (ItemNotFoundException ex1)
{
     try
     {
         cloudFilesProvider.CreateContainer(inStrContainerName);
         cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);
     }
     catch(Exception ex2)
     {
         return false;
     }
}

所以本质上如果容器不存在,那么它的 3 个单独的 API 调用。

有没有更有效的方法来做到这一点?

4

1 回答 1

4

您可以通过将代码减少到以下两行来简化代码。

cloudFilesProvider.CreateContainer(inStrContainerName);
cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);

CreateContainer调用已经存在的容器是安全的。ContainerCreated如果容器已创建,或者ContainerExists容器由于已存在而未创建,则返回。

PS:方法的返回值(带有上述信息)IObjectStorageProvider将在 1.2.0.0 版中得到很好的记录。


编辑:要减少代码进行的 API 调用次数,您可以使用如下所示的缓存类。CreateIfNecessary方法仅在以前不知道容器存在时才尝试创建容器。该ClearCache方法提供了一种手动方法,即使您删除了容器,也可以继续使用缓存。

此代码目前未经测试。

public class ContainerManager
{
    private readonly CloudFilesProvider _provider;
    private readonly string _region;
    private readonly bool _useInternalUrl;
    private readonly CloudIdentity _identity;

    private readonly HashSet<string> _containers = new HashSet<string>();

    public ContainerManager(CloudFilesProvider provider, string region, bool useInternalUrl, CloudIdentity identity)
    {
        if (provider == null)
            throw new ArgumentNullException("provider");

        _provider = provider;
        _region = region;
        _useInternalUrl = useInternalUrl;
        _identity = identity;
    }

    /// <summary>
    /// Clears the cache of known containers.
    /// </summary>
    /// <remarks>
    /// <alert class="warning">
    /// If a container was deleted after this cache was in use, this method must be called or
    /// <see cref="CreateIfNecessary(string)"/> could fail to create a container which does not
    /// exist.
    /// </alert>
    /// </remarks>
    public void ClearCache()
    {
        lock (_containers)
        {
            _containers.Clear();
        }
    }

    /// <summary>
    /// Ensures that a container exists in the Cloud Files store.
    /// </summary>
    /// <remarks>
    /// <alert class="warning">
    /// If a container was deleted after this cache was in use, and <see cref="ClearCache()"/>
    /// has not been called, this method could fail to create a container which does not exist.
    /// </alert>
    /// </remarks>
    /// <param name="container">The name of the container to create.</param>
    /// <exception cref="ArgumentNullException">If <paramref name="container"/> is <c>null</c>.</exception>
    /// <exception cref="ArgumentException">If <paramref name="container"/> is empty.</exception>
    /// <returns><c>true</c> if the container was created; otherwise <c>false</c> if the container already existed.</returns>
    public bool CreateIfNecessary(string container)
    {
        if (container == null)
            throw new ArgumentNullException("container");
        if (string.IsNullOrEmpty(container))
            throw new ArgumentException("container cannot be empty");

        // don't try to create the same container multiple times
        if (_containers.Contains(container))
            return false;

        ObjectStore result = _provider.CreateContainer(container, _region, _useInternalUrl, _identity);
        if (result == ObjectStore.ContainerCreated || result == ObjectStore.ContainerExists)
        {
            lock (_containers)
            {
                // add to _containers even if the result is ContainerExists, because that
                // means it simply wasn't known to this cache.
                _containers.Add(container);
            }
        }

        // only return true if the container was actually created
        return result == ObjectStore.ContainerCreated;
    }
}
于 2013-08-05T23:21:22.923 回答