web-dev-qa-db-ja.com

Azure Data Lake AnalyticsでUTF-8ドキュメントでUTF-8エンコーディングエラーが発生するのはなぜですか?

不明なソースシステムからgunzipで圧縮されたドキュメントがあります。 7Zipコンソールアプリケーションを使用してダウンロードおよび解凍されました。ドキュメントは、UTF-8でエンコードされているように見えるCSVファイルです。

次に、圧縮直後にAzure Data Lake Storeにアップロードされます。次に、あるフォルダーから別のフォルダーにコピーするだけのU-SQLジョブセットアップがあります。このプロセスは失敗し、値のUTF-8エンコードエラーが発生します。

テスト

ストアからドキュメントをダウンロードして、Azureによってフラグが付けられたレコードを除くすべてのレコードを削除しました。 Notepad ++では、ドキュメントをUTF-8として表示します。ドキュメントを再度UTF-8として保存し、ストアにアップロードします。プロセスをもう一度実行すると、プロセスはその値をUTF-8として成功します

ここで何が欠けていますか?元のドキュメントが本当にUTF-8でない可能性はありますか?誤検知の原因となるものは他にありますか?私は少し困惑しています。

可能性

  • ドキュメントは本当にUTF-8ではなく、再コーディングする必要があります
  • 多分ファイルをアップロードしているメソッドはそれを再コード化しています
  • 多分7Zipはそれを間違って再コーディングしています

環境/ツール

  • Windowsサーバー
  • Python 2.7
  • Azure Data Lake Store
  • Azure Data Lake Analytics
  • 7Zip.exe
  • gz
  • Azure API

[〜#〜] usql [〜#〜]

スキーマを定義する基本のUSQLジョブだけが、すべてのフィールドを新しいディレクトリに選択します。ヘッダーを除外する以外に変換は行われません。ファイルはCSVで、文字列は二重引用符で区切られたカンマです。スキーマは、データ型に関係なくすべて文字列です。試行された抽出プログラムは、システム上のAzureのドキュメントによると、両方ともエンコードされたUTF8がデフォルトでUTF8に設定されていても、TEXTとCSVです。

その他の注意

  1. この同じドキュメントが過去にBLOBストレージにアップロードされ、Polybaseを介してエラーなしに同じ方法でAzure Data Warehouseにインポートされました。
  2. UTF-8エンコーディングエラーの原因となる値は、100万個の他のレコードの間で破損したURLです。
  3. UTF-8ドキュメントであるにもかかわらず、ASCII文字が入っているようです。
  4. ANSIに変換してASCII抽出プログラムを使用すると、ファイルは成功します。
  5. Azure Data Lake Analyticsでは、エンコードの問題であるため、エラーを無視することはできません。 Azure Data Warehouseでできるように、レコードをすべて一緒に無効にしたいと思います。
5
Fastidious

ノート

ここで説明することはいくつかあります。

  1. これを邪魔にならないようにするために:gz [ip]および7Zip.exeこれとは何の関係もありません。圧縮によってエンコードや元のバイトが変更されることはありません(それ以外の圧縮/解凍は信頼できません)。まあ、理論的には、そのうちの1つにバグがあり、解凍された出力が多少異なる場合がありますが、それは広範囲にわたる問題になると思います。これらのアルゴリズム、特にこれら2つのツールは、長い間、信頼できることが知られています。

  2. 覚えておいてください:ファイルは、テキストファイルであっても、文字ではなくbytesを含みます。これらのバイトは、文字のセット、別のセット、または何か他のものを表すことができます。しかし結局のところ、それは単なるバイトのコレクションです。したがって、Ãが表示された場合、それはファイルにÃがあるためではなく、現在Ãを表すものとして解釈されている1つ以上のバイトによるものです。それらの同じバイトが本当に他のものを表すものとして解釈されるべきであるかもしれません。また、同時に、別の解釈の下にある他のバイトシーケンスもÃを表す場合があります。

  3. 次に、あるフォルダーから別のフォルダーにコピーするだけのU-SQLジョブセットアップがあります。

    わかりました、これはここで赤信号を発生させます:なぜ「ファイルを単純にコピーする」とエンコードエラーが発生するのですか?エンコードエラーが発生する可能性があるのは、ファイルが読み取られている場合のみです。それ以外の場合は、ポイントAからポイントBに移動するバイトのコレクションです(または単に再リンクされていて移動していないだけです)。

  4. このプロセスは失敗し、値のUTF-8エンコーディングエラーが発生します:ée

    次に、別の重要なインジケーターを示します(一部のユーザーが誤って解釈している可能性があります)。エラーはUTF-8エンコードerrorです。これにより、次の2つのことがわかります。

    1. ファイルはすでにUTF-8として解釈されているため、バイトシーケンスは他のエンコーディング(Windows-1252、ISO-8859-1など)として解釈されていません。これは、é文字が既にUTF-8エンコードされたバイト(つまり0xC383C2A9)であり、代わりにUTF-8として解釈されて生成されるWindows-1252バイト(0xC3A9)ではないことを意味しますé
    2. それがエラーであるという事実は、éeがエラーではないことを意味します。なぜなら、それがエラーの場合、それを表示することができないからです。エンコーディングエラーは、バイトシーケンスがそのエンコーディングで文字を生成できない場合です。意味:éeシーケンスから欠落しているものがあります。 éeシーケンスは、ファイル内のバイトからデコードできるものの残りの部分である必要があります。 Unicodeはソフトウェアではなく仕様であることに注意してください。実装は各ベンダーに任されています。準拠した実装に関するガイドラインがあり、それらにはデコードエラーの処理方法が含まれます。ただし、柔軟性もあります。したがって、この場合、一部の実装ではハードエラーがスローされるか、「置換」文字�が表示されるか、その位置に何も表示されない場合があります。どちらの場合でも、文字通りに取られたéeシーケンスは、おそらく赤目であり、私たちが見ているべきものではありません。
  5. Notepad ++では、ドキュメントをUTF-8として表示します。ドキュメントを再度UTF-8として保存し、ストアにアップロードします。プロセスをもう一度実行すると、プロセスはその値をUTF-8として成功します

    OK。したがって、Notepad ++で、ファイルを開いたときに下部バーの右側に「UTF-8」と表示されても、必要に応じてファイルが実際にUTF-8としてエンコードされていることを保証します。これは、おそらく一般的なバイトシーケンスに基づく最良の推測です。代わりにエンコーディングインジケーターが "UTF-8-BOM"を示している場合、thatは、ファイルがUTF-8としてエンコードされていることを保証します。 「-BOM」は Byte Order Mark が存在することを示します。 BOMは、ファイルの先頭にあるオプションの2〜4バイトのシーケンスであり、非表示にする必要がありますが、ファイルのエンコーディングを示します。これはUnicodeでのみ使用できます。 UTF-16には2つの2バイトBOMがあり、1つはリトルエンディアン用で、もう1つはビッグエンディアン用です。また、UTF-32には4つのBOMが2つあり、それぞれのエンディアンに対応しています。エンディアンはUTF-8に適用されないため、UTF-8には3バイトのBOMが1つしかありません(コード単位が1バイトであるため、バイトの順序は1つだけです)。もちろん、BOMを持っているからといって、ファイルを読んでいる人がそれを尊重したり理解したりすることさえ保証されません。ここで紹介するケースでは、ファイルがすでにUTF-8ファイルとして読み取られているため、BOMがあったとしても結果には影響しません。また、Notepad ++éeを示し、が「UTF-8」を示す場合右下隅の場合、éを生成するためにUTF-1として読み取るように指示する必要があるのは、Windows-1252/ISO-8859-1ではなく、すでにUTF-8です。

  6. Notepad ++がファイルがUTF-8であると考えた場合、ファイルをUTF-8として保存するべきではありません本当に何かを変えました。他の何かが変わったに違いない。
  7. ファイルはCSVで、文字列は二重引用符で区切られたカンマです。

    そして:

    これは、100万件の他のレコードにまみれたURLです。

    それで、éeはそのフィールドのentire値ですか?ファイル内の二重引用符内にありますか? éeはURLではないようです;-)

    また、エラーに表示される値は、ファイルに表示される値と正確に一致していますか?その場合、この問題の原因となっているファイルに隠し文字がある可能性があります。

  8. ASCII文字がUTF-8文書であるにもかかわらず入ってくるようです。

    「ASCII」の文字とはどういう意味ですか? UTF-8の機能の1つは、最初の128個のコードポイント(U + 0000からU + 007F)のエンコーディングが標準のASCIIと同じであることです。これは、UTF-8の主要な設計目標でした。ACSIIとの完全な互換性(8ビット拡張ASCIIではなく、7ビット標準ASCII)。したがって、ドキュメントの大部分が米国英語の文字と句読点を使用している場合、はい、ファイルをASCIIまたはUTF-8として開いても同じように表示されるはずです。

  9. ANSIに変換してASCII抽出プログラムを使用すると、ファイルは成功します。

    これは当然のことです。 ANSI/ASCIIエンコーディングエラーが発生する可能性はないと思います。コードページWindows-1252で定義されていないコードポイント/値はわずかしかなく、通常は "非表示」の文字。

    もちろん、そのファイルに有効なUTF-8でエンコードされた文字がある場合、ANSIに変換すると「?」に変更されます。 Windows-1252で利用できない場合。

持ち帰り

  1. これがANSI/Windows-1252/ISO-8859-1でエンコードされたファイルであり、é0xC3A9のバイトシーケンスを示している場合、バイトシーケンスがUTF-8であるため、UTF-8エンコーディングエラーは発生しません。 0xC3A9éの有効なUTF-8です。
  2. エラー自体を表示できないため(そうでない場合、エンコードエラーではありません):
    1. éeはエラーではなく、エラーの結果です
    2. デコードできなかったものを確認するには、エンコードエラーのある行のexactバイトを確認する必要があります。
  3. ファイルをUTF-8としてインポートする必要があるとは何も言われていません。ファイルが(このファイルでなくても)Windows-1252、ISO-8859-1などにエンコードされていて、データがすべてファイル内で正しい場合、ファイルを強制的にUTF-8にしようとするのではなく、実際のファイルエンコーディングが何であるかをプロセス/ツールがファイルを読み取っていることを伝えることをお勧めします。 Windows-1252エンコードファイルをWindows-1252としてインポートしない理由はありません。

結論は:エンコーディングエラーのある行の元のバイトを確認せずに、推測/ wild-goose-chaseが多すぎます。その行があると、a)何が起こったか、b)どうやって進むかを決定するのに役立ちます。

バウンティのポスターがこの回答にコメントを追加して詳細を提供できる場合、特にエラーが発生しているexactバイトシーケンスは、これを解決するのに役立ちます。

3
Solomon Rutzky

UTF-8でエンコードされたファイルには、オプションでバイトオーダーマーク(BOM)を含めることができます。これは、ファイルがUTFエンコードされていることを消費ソフトウェアに示す「マジックナンバー」です。さらに複雑にするために、BOMはビッグエンディアンまたはリトルエンディアンにすることができます。

Notepad ++では、これらすべてが[エンコード]メニューから表示されます。私はあなたがあなたのファイル(またはそれの切り取られたコピー)のためにこれらをいじくり回して、もしあれば、何が機能するかを確認することをお勧めします。

1
Michael Green