目前我这样做
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调用。
有更有效的方法吗?
答案 0 :(得分:4)
您可以通过将代码缩减为以下两行来简化代码。
cloudFilesProvider.CreateContainer(inStrContainerName);
cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);
CreateContainer
可以安全地调用已存在的容器。如果创建了容器,则返回ContainerCreated
;如果由于容器已经存在而未创建容器,则返回ContainerExists
。
PS:版本1.2.0.0中将详细记录IObjectStorageProvider
方法的返回值(包含上述信息)。
编辑:要减少代码所做的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;
}
}