メモ帳でJPG画像を開き、すべての「テキスト」を新しいメモ帳ファイルに貼り付け、.JPGに変更して、それが開かなくなった。どうして?


82

この現象は私に尋ねる質問を残しています。

詳細な実験は次のとおりです。私のOSはWindows 7 x64 SP1です。

  • 拡張子を変更するだけで、画像(JPG)ファイルをTXTに変更しました(または、メモ帳でJPGを開くこともできます)。

次のスクリーンショットのように、奇妙に見えるテキストのシーケンスのように見えるはずであり、それらのいくつか(非常にまれ)は実際に意味があります。

サンプルJPGテキスト

  • 折り返しを無効にし、Ctrl + Aを使用してすべてのテキストを選択しました(何も見逃さないようにするため)
  • コピーしたテキストを別の空のTXTファイルに貼り付けてJPGとして保存し、新しいファイルサイズを元のJPGと比較しました。すべて(元のJPG、変換されたTXTファイル、新しく作成されたTXTファイル)は、まったく同じサイズ(バイト単位)です。

開こうとすると、Windowsは「ファイルが破損、破損、または大きすぎるため、Windows Photo Viewerでこの画像を開けません」表示します

私も別の方法を使用してテストしてみました:メモ帳でJPGをオープン、私はカットONEし、ファイルを保存します(2行目の最初の文字など)覚えやすい場所から知られている文字を。ビューアはもちろん同じメッセージを表示します。その後、もう一度開いて文字を正確な場所に貼り付けました(メモ帳は、ウィンドウの位置、ラッピング、フォントサイズなどの終了状態を記憶しているので、これを正しく取得しても問題ありません)

それでも同じエラー。これを試してアイデアを得ることができます。小さな写真を選択することを忘れないでください。さもないと、メモ帳は古いさびた男のように振る舞います。

この現象の原因は何だったのでしょうか?


4
fcコマンドを試してください。cmdプロンプトを開き、do- C:\blah>fc file1 file2 ファイルのサイズは同じでも異なる場合があります。(通常、ランダムな変更によってファイルが同じサイズのままになることはありませんが、簡単に変更できます)。fcコマンドは、何が起こっているのかを調査する際に非常に役立ちます。xxdコマンドも使用できます。これはcygwinにあり、vim7にも付属しています。xxd -p file1これは、ファイルの16進数をダンプします。2つのファイルの16進数をthatおよびfcと比較できます。または、メモ帳でヘックスを開き、alt-tabで2つのメモ帳ウィンドウ間をフリックします。
barlop

22
メモ帳のような単純なテキストエディターでバイナリファイルを読み取ろうとしています。ANSIエンコーディングを正しく読み取ることができないため、変換されます。保存すると、ファイルはバイナリではなくなり、パーサーはファイル内のデータを読み取ることができなくなります。(XMLベースのファイル保存とバイナリファイルの保存の違いを調べるのは興味深いトピックです。)Notepad ++で同じ実験を試してみると、試してみたことに成功するでしょう。
woutervs


3
興味のある方へ:Vimで画像を編集できます:ただし、トリックは、VimがXPM形式(プレーンASCII)でファイルを変換することです。
ボルデウィン

4
簡単に言えば、メモ帳はファイルを変更してから表示します。
デレク朕會功夫14

回答:


81

ファイルを開くために使用されるエンコードに応じて、異なる動作が表示される場合があります。Windows 7のメモ帳では、ANSI、UTF-8、Unicode、またはUnicodeビッグエンディアンでファイルを開くことができます。

この問題は、gimpで作成され、ANSIエンコーディングで画像ファイルを開いて保存する小さな2x2ピクセルのjpeg画像でテストしました。元のイメージと保存されたイメージの両方を16進エディターで開くと、すべての00シーケンス(2桁の16進数、NUL制御文字)が20(スペース文字)に変換されていることがわかります。

16進エディターですべて20を00に戻すと、イメージ形式が復元されます。

私はそれを少しグーグルで調べましたが、なぜそうするのかを説明する参考文献は見つかりませんでした。それについて警告する投稿への参照のみ(Googleキャッシュリンク、ページは利用できません)。

ファイルをUTF-8として保存/開くと、NUL文字はまだスペースに変換されますが、シングルバイト文字からUTF-8マルチバイトシーケンスへの変換により、結果のファイルサイズも大きくなります。

ファイルをUnicodeとして保存/開くと、NUL文字はまだスペースに変換されているように見えますが、ファイルの先頭にBOMも追加されています。


22
0x00は、C文字列の文字列ターミネータです。テキストファイルにそれらを含めるべきではないため、それらを置き換えた可能性があります。メモ帳は非常に古いプログラムです。
ゾンダー

25
notepad.exeが.NET実行可能ファイルであるとは思えません。
knittl

10
@Bakuriu AC文字列は、ほとんどの場合ファイルに存在できます。それらを含む多くのファイル形式を考えることができます。また、Windowsアプリに同梱されているアプリの大半は、.NETではなくネイティブです。とは言っても、メモ帳はnullで終わる文字列をファイルに書き込みません。
キャリーグレゴリー

4
@Bakuriu:通常、Windowsプログラムは.Netで作成されていません。C / C ++であり、コアがネイティブです。マイクロソフトが開発した.Netアプリケーションの1つはライブライターでしたが、現在は廃止されています。
bhathiya-perera

5
@ SJuan76え?C ++はという名前のデータ型を定義しませんbyte。おそらく他の言語を考えているのでしょう。また、アプリケーション開発者は、必要に応じてC文字列の使用など、適切と思われるバイナリデータを処理できます。前に言ったように、C文字列を含む多数のバイナリファイル形式を考えることができます。
キャリーグレゴリー

37

失敗する理由:

Windows APIのテキストボックスではヌル終端ASCIIZ(文字配列、ポインター)のみが許可されているため(ASCII code 32)、メモ帳はNUL などの文字に対してスペース文字を作成します。最初のNULで切断されます。(ASCII code 0)char *

これは、Windows APIの大部分がC言語で記述されており、ヌル文字で終了する文字列が一般的な機能の1つであるためです。最新のWindowsとUnicodeが同じnullで終了する文字列と見なされる場合でも。したがって、メモ帳は単にスペースに置き換えて、ファイル全体を表示できるようにします。

そのため、ファイルを保存すると破損します。

wikipedia-nullで終了した文字列


さらに調査する方法:

比較(商用、試用)超えたようなコンパレータを使用して、文字置換の効果を確認できます。他のバイナリ比較ツールも参照してください。

16進比較

:(20)16 =(32)10


メモ帳が大きなファイルでゆっくりと動作する理由

各文字をチェックし、特殊文字をスペースに置き換えます。他のソフトウェアはメモリ内変換を行いません(少なくともメモ帳としてのプリミティブではありません)。特殊文字のレンダリング方法が異なるだけです。そして、高度なバッファリング技術を使用します。


Notepad.exeを調べる(XP 32ビット)

(私はまだC ++で書かれているか、少なくとも同等のリンカを使用していると仮定しています

メモ帳

PEiDツールを使用してます(PE + / 64 exeの導入により開発が停止しました)

PEiDは、Universal Extractorの binフォルダーにバンドルされています

メモ帳を抽出しました。Windows XP ISOからのex_ファイルは明らかに。やってみて。7zを使用したcabファイルの抽出です。

警告!ウイルススキャナは、Universal Extractor / PEiDをハッキングツールまたはウイルスとして検出する場合があります。信頼しないで、ダウンロードしないでください!!


Windows APIに関する詳細情報

クレジット:Jason C

テキストボックスだけではありません。WM_SETTEXTは一般に、文字列の長さを指定するパラメータを提供しません。文字列は常にnullで終了すると想定されます。文字列の長さを指定したカスタムメッセージを含むカスタムテキストボックスをいつでも作成できますが、メモ帳や他のほとんどのプログラムは合理的に作成しません。また、関数SetWindowTextは長さパラメーターも提供しません。


1
Windows XPのバージョンにバンドルされているメモ帳実行可能ファイルのプロパティシートを表示するのは少し奇妙ですが、ウィンドウテーマによって判断すると、明らかにWindows 8のいくつかのバージョンを実行しています。ツールセットのバージョン7.1。これは、Windows XPおよび関連ユーティリティをコンパイルするために使用したものです。メモ帳のWindows 8バージョンは、SDKツールの新しいバージョンで間違いなくコンパイルされます。
コーディグレー14

2
テキストボックスだけではありません。WM_SETTEXT一般に、文字列の長さを指定するパラメータは提供されず、文字列は常にnullで終了すると想定されます。文字列の長さを指定したカスタムメッセージを含むカスタムテキストボックスをいつでも作成できますが、メモ帳や他のほとんどのプログラムは合理的に作成しません。
ジェイソンC

@BhathiyaPerera私は、コメントに情報を追加することで行った作業のレベルに満足しているからです。必要に応じて、その情報を使用して回答を改善できます。
ジェイソンC 14

28

メモ帳は、すべての特殊/拡張文字をそのまま保持するわけではありません。私はすぐにこの動作のリファレンスを持っていませんが、これは、例えばメモ帳がCRLFとnull(0x00)に変換するUNIXスタイルの行末LFの場合に当てはまることがわかりましたが、無視されます。JPGなどのバイナリファイルでは、メモ帳で保持されない文字がランダムに出現する可能性があります。HEX対応エディターで実験してみてください。適切なリファレンスを見つけて、HEXエディターをテストしたら、回答を更新します。

更新:著名なプログラマーエディターをいくつか試しましたが、すぐに使えるのはそのうちの1人、MaëlHörzによるHxDだけでした。これまでHxDを使用したことはありませんが、このStack記事、Notepad ++用の16進ビューア/エディタプラグインに対する回答のおかげで見つかりました。

数分努力しても機能しなかった他のエディターは、Notepad ++、Notepad2、UltraEdit(v17.3、旧バージョン)です。これらのいくつかには、最初の数バイトのコピー/貼り付け、JPEG ファイル署名のマジックナンバー FF D8 FFに問題がありました。たぶん、彼らは私が現時点で持っている時間よりも少し手間をかけて作業するでしょう。


Sublime Text(2/3)は、バイナリファイルを16進形式で表示して自動的に開きます。例として、「開く」をクリックするだけでJPEGファイルを開始します。puu.sh
aaAVx

3
実際、メモ帳がLFをCRLFに変換するよりも頻繁に、LFをそのままにして、改行がまったくないかのようにテキストを表示します!
モシェカッツ

6

以前は、その日のライトバックでこれを行うことができました。これはWindows 3.1の標準プログラムでしたが、Windows 95に含まれているかどうかは思い出せません。書き込みを行うと、開くことができるファイルのバイナリセーフ編集が可能になります(おそらく非常に制限されたファイルサイズ)。メモ帳は間違いなくバイナリセーフではありません(テキストは同じままですが、非テキスト文字の実際のバイト[制御コード]は変更される可能性があります)。これがJPGサンプルが機能しない理由です。Write(および非常に古いWindows)のコピーを取得して、もう一度実験してみてください!

よると、Wikipediaの「Windows書き込み」の記事の書き込みは、Windows NT 3.5まで含まれていました。Windows 95以降ではワードパッドに置き換えられました。write.exeWindowsディレクトリにまだ存在していましたが、単にワードパッドを開くためのラッパーでした。


5

エンコードの問題ではなく、文字セットの問題だと思います。JPG形式は基本的にバイトストリームです。したがって、NUL、ETX、STX、SOH、DLEなどの非印刷文字を許可します。

Microsoft Notepadは、これらの印刷できない文字を表示できません。ヌル文字のスペースなど、何らかの種類のプレースホルダーを表示する場合があります。そのため、メモ帳でファイルを開くと、実際のコンテンツは表示されませんが、選択したエンコード(utf-8、utf-16など)によってデコードされ、非文字列を除く特定の文字セット(unicode、asciiなど)印刷可能な文字。

表示されているすべてのテキストを選択してテキストをクリップボードにコピーする場合、プレースホルダーを含む印刷可能な文字のみをコピーします。したがって、ヌル文字をスペースに自動的に変換し、他の印刷不能文字を完全に無視します。

したがって、基本的にはこの方法でコンテンツを失うだけです。代わりに16進エディタを使用すると、すべてのコンテンツが完全にコピーされます。


更新:Bhathiya Pererasの答えは正しい:https ://superuser.com/a/782885/322784 テキストをクリップボードにコピーするとき、印刷できない文字は無視されません。


すべてのファイルは「基本的にバイトストリーム」です。
ジェイソンC 14

1
@JasonC私は反対だろう。すべてのファイルはバイトストリームとして読み取ることができます。XMLファイルなどの構造化ファイルは、データのストリームとして読み取ることはできません。コンテンツは、ファイルの終わりが読み取られるまで有効ではありません。ハーフjpgのカットはまだ有効であり、表示できます。画像の半分が欠落しています。
sbecker

それについて意見の相違の余地は本当にありません。:) XMLは、他の何かと同様にバイトのストリームであり、XMLは(文字エンコーディングとともに)それらのバイトのフォーマットを定義します。確かにデータのストリームとして読むことができます。たとえば、16進エディタで開きます。そのデータのストリームは、たまたまXMLとして解析可能です。
ジェイソンC 14

@JasonCそれについて実際に議論することはできません。:)Touché!
sbecker 14

2

JPEGファイルには、一部のフィールドを除く非テキストデータが含まれています。基本的に、0から255の間のバイト値はすべて、特に擬似ランダムデータを含むエンコードされた圧縮画像を表す領域で見つかります。

ただし、メモ帳はデータをデフォルトでANSIテキストとして扱うため、元のデータを変更するさまざまな処理を次のように行います。

  • 有効なANSIテキストには意味がないため、特殊/未定義/禁止文字をマッピングするバイトを置き換えます

  • ヌル文字、行末およびファイルの終わりのシーケンスをWindows / DOS規則に再エンコードします

つまり、データを編集してテキストとして保存すると、最良の場合はjpegが変更され、最悪の場合は使用できなくなります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.