
2026/05/05 15:14
Windows にバイナリファイルとして記述中であることをどのように通知すべきでしょうか。
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
Windows は、基本的には Unix 系のシステムとは異なる点に、任意のファイルに対して改行コードやエンコーディング形式などの自動テキスト変換をネイティブで処理しないという事実があります。この区別により、開発者はオペレーティングシステムのデフォルト動作に依存するのではなく、ファイルモードを明示的に管理し、これらの複雑な変換をより高レベルのライブラリに委任する必要があります。例えば、特定の ioctls を使用するというレガシーな MS-DOS の手法は、通常のディスクファイルに対して適用しようとすると失敗します。Windows API は、通常のハンドルに対する此类のデータ変換に対応していないためです。また、
AH=4401h などのデバイス固有の制御を使用するハンドルの場合、それは文字装装置のみを対象としているためエラーになります。したがって、C ランタイム内でテキストモード(改行コードの変換を処理)とバイナリモード(生のデータ向け)の間で慎重に選択する必要がありますが、そのモードフラグは API 自体ではなくランタイムによって管理されます。レイモンド・チェン氏のような有識者——30 年以上の Windows に関与し、2003 年に「The Old New Thing」を設立し、関連書籍も執筆しているベテラン——は長年以来、「古いシステムに似た自動動作を期待することは誤解である」と強調しています。彼の洞察は頻繁に Windows Dev Docs の Twitter アカウントで共有されています。そのため、将来的なアプリケーションではネイティブのファイル変換機能を想定すべきではなく、代わりに外部ライブラリを統合するか、または独自のロジックを実装することでテキストファイルの適切な処理を保証し、プラットフォーム固有の動作の欠如により引き起こされる潜在的なデータ破損や予期せぬ失敗を防ぐ必要があります。本文
顧客から、テキストモードとバイナリモードでファイルをオープンする際に、Windows にその事実をどのように伝えればよいかという質問がありました。そうすれば、Windows が必要に応じて文字変換を実施できます。例えば、改行記号(LF)の前に carriage return(CR)を追加したり、ASCII を Unicode に変換したりといった処理です。
Windows の側では、ファイルがバイナリなのかテキストなのかを知る手段はありません。Windows にとってファイルとは単なるバイトの列に過ぎず、その解釈はすべてアプリケーション側が担う必要があります。ある意味では、すべてのファイルをバイナリファイルと見なしてよいということです。CR を LF の前に挿入したいのであれば、ご自身で実装する必要があります。
よくあるケースとして、C ランタイムのようなより高层次のライブラリをご利用になっている場合です。その場合は、ライブラリ自体に文字変換を代行してもらうことができます。例えば、「w」モードでファイルを開くことで、ランタイムライブラリがそのファイルをテキストファイルとして扱うよう指示したり、「wb」モードでオープンすることでバイナリファイルとして扱ったりします。ただし、この処理は Windows 自身ではなく、ランタイムライブラリの内部で行われます。つまり、ランタイムライブラリが必要な変換を実行し、結果として生成されたバイナリデータを Windows(具体的には WriteFile の呼び出し元)に渡すという仕組みです。WriteFile にデータが届いた時点で、さらに何らの変換も発生しません。
「でも待ってください。旧来の MS-DOS の IOCTL で、AH=4401h(デバイス情報の設定)があり、DX に入力されるフラグのビット 5 が RAW(バイナリ)モードを示すという話があるんです。では、Windows 版のこの IOCTL は存在するのでしょうか?」
よく検討すると、その MS-DOS の IOCTL は文字デバイス(character device)のみを対象としており、ディスクファイルを指定しようとすると ERROR_INVALID_FUNCTION を返してしまうことが分かります。
ioctl_check_permissions: CMP AL,2 JAE ioctl_control_string CMP AL,0 MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid] JZ ioctl_read ; バイトを読み取る場合 OR DH,DH JZ ioctl_check_device ; データで設定可能なか? error error_invalid_data ; 否(DH <> 0) ioctl_check_device: TEST AL,devid_ISDEV ; このハンドルに対して設定できるか? JZ ioctl_bad_fun ; 不可能:対象はファイルであるため ... ioctl_bad_fun: error error_invalid_function
この IOCTL は、入力に対し行バッファリングを実行するかどうかといったコンソールの動作設定を伝えるために利用可能です。Win32 における同等な機能は SetConsoleMode で、これは概ね Unix の stty に相当します。しかしながら、ファイルに対するコンテンツの変換を行いたいのであれば、ご自身で実装するか、あるいは他の手段(例:ランタイムライブラリに任せる)を選ぶ必要があります。
カテゴリー・トピック: 著者
レイモンドは Windows の進化に関わって 30 年以上を経ています。2003 年、彼は「The Old New Thing」というウェブサイトを立ち上げましたが、その人々の想像力を超えたほどに人気を博したことは、今でも彼をドキドキさせるほどの出来事です。このウェブサイトは結果として『The Old New Thing』というタイトルの本(Addison Wesley, 2007 年出版)を生み出しました。時には Windows Dev Docs の Twitter アカウントにも出演し、「役に立たない情報」を伝える話をつまびらかにしています。