将文件上载到Azure存储会导致错误:此流不支持超时

时间:2014-01-05 02:40:36

标签: c# asp.net azure filestream azure-storage-blobs

我有一个包含文件上传到Azure存储的表单。 这是调用ToStream()方法的地方:

 Image img= Image.FromStream(file.InputStream, true, true);
 if (img.Height != height || img.Width != width)
 img= img.GetThumbnailImage(width, height, null, new IntPtr());
 img.ToStream().SaveAsBlob(blobname, filename);

这是ToStream()方法:

public static Stream ToStream(this Image image)
{
    Stream ms = new MemoryStream();
    image.Save(ms, ImageFormat.Jpeg);
    ms.Position = 0;
    return ms;
}

我得到的错误是:

  image.Save(ms, ImageFormat.Jpeg);

错误是

'ms.ReadTimeout' threw an exception of type 'System.InvalidOperationException'
'ms.WriteTimeout' threw an exception of type 'System.InvalidOperationException'

它的基础是:

Timeouts are not supported on this stream 

这是SaveAsBlob()方法:

public static void SaveAsBlob(this Stream stream, string containername, string blobname)
{
     BlobHelper helper = new BlobHelper();
     CloudBlobContainer container = helper.ContainerGet(containername);
     helper.BlobDelete(container, blobname);
     helper.BlobAdd(container, blobname, stream);
}

BlobHelper类:

public class BlobHelper
{
    private const int MaxBlockSize = 4000000;

    private CloudStorageAccount _CloudStorageAccount { get; set; }

    public BlobHelper()
    {
        this._CloudStorageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings[StaticConfiguration.ConnectionString].ConnectionString);
    }

    public CloudBlobContainer ContainerGet(string adi)
    {
        CloudBlobClient blobClient = _CloudStorageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference(adi);
        container.CreateIfNotExists();
        BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
        containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
        container.SetPermissions(containerPermissions);
        return container;
    }

    public Uri BlobAdd(string filePath, CloudBlobContainer container)
    {
        byte[] fileContent = File.ReadAllBytes(filePath);
        string blobName = Path.GetFileName(filePath);
        return BlobAdd(fileContent, container, blobName);
    }

    public Uri BlobAdd(CloudBlobContainer container, string adi, Stream stream)
    {
        adi = adi.Replace("//", "/");
        byte[] content = new byte[stream.Length];
        stream.Read(content, 0, (int)stream.Length);
        return BlobAdd(content, container, adi);
    }

    public Uri BlobAdd(byte[] fileContent, CloudBlobContainer container, string blobName)
    {
        CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

        HashSet<string> blocklist = new HashSet<string>();
        foreach (FileBlock block in GetFileBlocks(fileContent))
        {
            blob.PutBlock(
                block.Id,
                new MemoryStream(block.Content, true),
                null
                );

            blocklist.Add(block.Id);
        }
        blob.PutBlockList(blocklist);
        blob.FetchAttributes();
        blob.Properties.CacheControl = "public, max-age=31536000";
        blob.SetProperties();
        return blob.Uri;
    }

    private IEnumerable<FileBlock> GetFileBlocks(byte[] fileContent)
    {
        HashSet<FileBlock> hashSet = new HashSet<FileBlock>();
        if (fileContent.Length == 0)
            return new HashSet<FileBlock>();

        int blockId = 0;
        int ix = 0;

        int currentBlockSize = MaxBlockSize;

        while (currentBlockSize == MaxBlockSize)
        {
            if ((ix + currentBlockSize) > fileContent.Length)
                currentBlockSize = fileContent.Length - ix;

            byte[] chunk = new byte[currentBlockSize];
            Array.Copy(fileContent, ix, chunk, 0, currentBlockSize);

            hashSet.Add(
                new FileBlock()
                {
                    Content = chunk,
                    Id = Convert.ToBase64String(System.BitConverter.GetBytes(blockId))
                });

            ix += currentBlockSize;
            blockId++;
        }

        return hashSet;
    }

    public void BlobGet(CloudBlobContainer container, string adi, Stream stream)
    {
        CloudBlockBlob blob = container.GetBlockBlobReference(adi);
        blob.DownloadToStream(stream);
    }

    public IEnumerable<IListBlobItem> BlobListGet(CloudBlobContainer container)
    {
        return container.ListBlobs();
    }

    public void BlobDelete(CloudBlobContainer container, string adi)
    {
        CloudBlockBlob blob = container.GetBlockBlobReference(adi);
        blob.DeleteIfExists();
    }
}

1 个答案:

答案 0 :(得分:1)

如果在调用container.CreateIfNotExistscontainer.SetPermissions时收到403错误,请确保您使用的连接字符串包含有效的帐户密钥。您可以在Azure门户中进行检查,然后重新生成密钥并替换web / app.config中的旧密钥。