21

タスク

元のファイル名でファイルをアップロードし、ファイル名をにAzure Blob Storage割り当てますmeta-dataCloudBlob

問題

これらの文字は使用できませんが、名前meta-dataとして使用できます。blob

š Š ñ Ñ ç Ç ÿ Ÿ ž Ž Ð œ Œ « » éèëêð ÉÈËÊ àâä ÀÁÂÃÄÅ àáâãäå ÙÚÛÜ ùúûüµ òóôõöø ÒÓÔÕÖØ ìíîï ÌÍÎÏ

質問

  • これらの文字を?に保存する方法はありmeta-dataますか?この例外の原因となる設定が欠落していますか?
  • これらの文字のほとんどは、一部の言語では標準のグリフですが、それをどのように処理するのでしょうか。
  • この問題についてアドバイスする利用可能なドキュメントはありますか?blob命名規則を見つけましmeta-dataたが、データ自体については何もありません!

コード

var dirtyFileName      = file.FileName;
var normalizedFileName = file.FileName.CleanOffDiacriticAndNonASCII();

// Blob name accepts almost characters that are acceptable as filenames in Windows
var blob = container.GetBlobReference(dirtyFileName);

//Upload content to the blob, which will create the blob if it does not already exist.
blob.Metadata["FileName"] = normalizedFileName;
blob.Attributes.Properties.ContentType = file.ContentType;

// ERROR: Occurs here!
blob.UploadFromStream(file.InputStream);

blob.SetMetadata();
blob.SetProperties();

エラー

例外

参考文献


回避策

ファイル名の不正な文字は氷山の一角に過ぎず、この質問の目的のためにのみ拡大されています。全体像は、を使用してこれらのファイルにインデックスを付けることです。Lucene.netそのため、に多くのファイルをmeta-data保存する必要がありblobます。すべてを個別にデータベースに保存することを提案しないでください。これまで、発音区別符号を含むファイルを1つしか見つけられなかったのは幸運でした。

そのため、現時点ではmeta-data、回避策としてファイル名をに保存しないように努めています。

4

4 に答える 4

18

内のデータとして有効なのは文字のみであるというazure-sdk-for-netGitHubのチームからの確認がありました。ASCIIblob meta-data

joeg
のコメント:blobメタデータでサポートされている文字はASCII文字である必要があります。これを回避するには、文字列(パーセントエンコード)、base64エンコードなどをエスケープします。

GitHubのソース

したがって、回避策として、次のいずれかを実行します。

  • joegが提案するように、文字列をエスケープ(パーセントエンコード)、base64エンコードなど
  • 私が他の答えで述べたテクニックを使用してください。
于 2013-02-20T11:37:15.413 に答える
8

実際に問題を解決する答えが得られない限り、この回避策は上記の問題の解決策です。

回避策

これを機能させるために、私は以下の方法を組み合わせて使用​​しています。

  1. 可能なすべての文字をASCII/英語の同等の文字に変換します
  2. このクリーンアップをエスケープする無効な文字は、文字通り文字列から削除されます

しかし、データが失われているため、これは理想的ではありません。

ASCIIへの発音区別符号

/// <summary>
/// Converts all Diacritic characters in a string to their ASCII equivalent
/// Courtesy: http://stackoverflow.com/a/13154805/476786
/// A quick explanation:
/// * Normalizing to form D splits charactes like è to an e and a nonspacing `
/// * From this, the nospacing characters are removed
/// * The result is normalized back to form C (I'm not sure if this is neccesary)
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ConvertDiacriticToASCII(this string value)
{
    if (value == null) return null;
    var chars =
        value.Normalize(NormalizationForm.FormD)
             .ToCharArray()
             .Select(c => new {c, uc = CharUnicodeInfo.GetUnicodeCategory(c)})
             .Where(@t => @t.uc != UnicodeCategory.NonSpacingMark)
             .Select(@t => @t.c);
    var cleanStr = new string(chars.ToArray()).Normalize(NormalizationForm.FormC);
    return cleanStr;
}

非ASCIIバーニネーター

/// <summary>
/// Removes all non-ASCII characters from the string
/// Courtesy: http://stackoverflow.com/a/135473/476786
/// Uses the .NET ASCII encoding to convert a string. 
/// UTF8 is used during the conversion because it can represent any of the original characters. 
/// It uses an EncoderReplacementFallback to to convert any non-ASCII character to an empty string.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string RemoveNonASCII(this string value)
{
    string cleanStr = 
           Encoding.ASCII
                   .GetString(
                              Encoding.Convert(Encoding.UTF8,
                                               Encoding.GetEncoding(Encoding.ASCII.EncodingName,
                                                                    new EncoderReplacementFallback(string.Empty),
                                                                    new DecoderExceptionFallback()
                                                                    ),
                                               Encoding.UTF8.GetBytes(value)
                                               )
                              );
    return cleanStr;
}

回避策は明らかに理想的ではなく、なぜこれが不可能なのかも意味がないので、私は本当に答えを得たいと思っています!

于 2013-02-15T16:51:51.737 に答える
4

bPratikによる回答を拡張するために、Base64エンコーディングメタデータが適切に機能することがわかりました。この拡張メソッドを使用して、エンコードとデコードを行います。

    public static class Base64Extensions
    {
        public static string ToBase64(this string input)
        {
            var bytes = Encoding.UTF8.GetBytes(input);
            return Convert.ToBase64String(bytes);
        }

        public static string FromBase64(this string input)
        {
            var bytes = Convert.FromBase64String(input);
            return Encoding.UTF8.GetString(bytes);
        }
    }

次に、BLOBメタデータを設定する場合:

blobReference.Metadata["Filename"] = filename.ToBase64();

そしてそれを取得するとき:

var filename = blobReference.Metadata["Filename"].FromBase64();

検索の場合、インデクサーに提示する前にファイル名をデコードするか、元のファイル名をまだ使用していると仮定して、BLOBの実際のファイル名を使用する必要があります。

于 2016-09-07T07:53:50.737 に答える
0

上記のリストが網羅的である場合は、メタデータをHTMLにエンコードし、必要なときにデコードできるはずです。

var htmlEncodedValue = System.Web.HttpUtility.HtmlEncode(value)
var originalValue = System.Web.HttpUtility.HtmlDecode(value)
于 2013-06-11T09:12:16.313 に答える