人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

コンピュータで、「ファイルを開く」という概念がよく理解できません。裏側で何が行われているのでしょうか?

私が理解していること
・コンピュータは0と1しかあつかえない
・ハードディスクは、磁石がのった円盤で、磁力の向きで1,0を表現している
・ファイル読み取りは、これらの1,0の並びを認識すること
・ファイル書き込みは、これらの並びを変更すること

では、開く、閉じるは?

シェルで、
echo "hello" > hello.txt
と実行すると、物理的にはHDDにデータが書き込まれます。
それは理解できます。

しかし、C言語などで

FILE *fp;
fp = fopen( "test.txt", "r" );

としたとき、fopenの裏側では何が行われているのでしょうか?
ファイルポインタ(とかファイルハンドル)とは一体何なんでしょうか?

読み取り、書き込みは、物理メディアに対しての物理的動作をイメージできますが、
オープン、クローズは何もイメージできません。
オープン、クローズとは何でしょうか?

●質問者: DQNEO
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 13/13件

▽最新の回答へ

1 ● kodairabase
●16ポイント
ファイルを開く
読み取りまたは書き込みを開始することの宣言。読み込みまたは書き込みを行うための領域が、メモリ上に確保される。この領域に対する目印が「ポインタ」。

ファイルを閉じる
読み取りまたは書き込みを完了することの宣言。読み込みまたは書き込みを行うための領域が、メモリ上から廃棄される。(書き込みの場合は、ディスクに書き込んでから廃棄される)

ファイルストリーム
http://www.geocities.jp/ky_webid/cpp/library/033.html


DQNEOさんのコメント
ファイルを開く:宣言してメモリ確保ということは、fopenしたプロセス内のメモリの中だけの動きであって、実際の(HDDなどの)物理メディア上では何も動かないのでしょうか?

DQNEOさんのコメント
結局、磁力ののった円盤はそのときどうなるのでしょうか?

kodairabaseさんのコメント
>実際の(HDDなどの)物理メディア上では何も動かないのでしょうか? アプリケーションで「開く/閉じる」と言う場合と、OSで「開く/閉じる」と言う場合とで異なってきます。 Windowsで「読み込みで開く」と言う場合、そのファイルの先頭から一定量のデータを先読みします。「書き込みで開く」と言う場合、指定された名前のファイルをあらかじめ作成します。 一方、アプリケーションで「開く」と言う場合、アプリケーション毎に挙動が異なります。

DQNEOさんのコメント
むむむ・・よくわからなくなってきました。「開く」と「読む」は違うと思ったのですが。

多食斎友好=世田介さんのコメント
『「開く」と「読む」は違うと思ったのですが。』確かに違います、回答者の文を読めばそう言う理解にならないと思いますが。 紙製の「ノート」をイメージしてみて下さい。 ノートを開く事、つまり「読み書き」する為の準備が「開く」です。 「開いた」あと、書き込まれた事を「読んだり」「書き込みを修正したり」「新たに書き加えたり」「消す事」ができます。 「閉じる」は「読み書き」作業が終了した後、「読み書き」できない状態にすることです。 コンピュタのメモリーの場合、読み書き(書き換え・消去を含む)のできるものをRWM、読むことだけ出来るものをROMといいます。(1度だけ、書き込みができるものもありますが)そこが「紙製」と少し違いが有りますが、兎に角「開く」「閉じる」の概念は共通です。 既に印刷された本などは、「開いて」も基本的には内容を「読む事」だけできます、「消去・修正・追加書き込み」はできません。もっとも、行間にメモや塗りつぶしはできますが。

2 ● hirokiky
●16ポイント

残念ながら私の知識では回答することはできませんが、調べてみると面白そうな pdf を見つけたのでリンクを貼っておきます。

"Linuxカーネル2.4の設計と実装。ファイルシステム(後編)
http://www.mars.dti.ne.jp/~otk/bak/200105-linuxkernel24.pdf

この pdf の、図14のあたりにファイルのオープンやクローズについても書かれています。斜め読みしただけですが、参考になると思います。

あとは「C言語によるUNIXシステムプログラミング入門」という本が参考になるとおもいます。fopen などの関数の核になる、よりハードウェアに近い関数(低水準入出力関数)やファイルポインタが指しているもの(利用者ファイル記述子表)などについての説明もあります。

私が回答できるのはこれだけですので、参考程度に思ってください。
面白い質問だと思うので、私も他の方の回答を楽しみにしています。


DQNEOさんのコメント
なるほどなるほど。すごい難しいですね。 でもちょっと答えに近づいた気がします。 ありがとうございます!

3 ● HowAreYou
●16ポイント

基本的にプログラムは直接メディアにアクセスしてデータを読み書きするのではなくて、OS にお伺いを立てて行います。
OS は「ファイルオープンしたいんですけどー」という申請を受けて、そのファイルがシステム的に保護されてないかとか、他のプログラムから「独占的に使いたいから他のプログラムに使わせちゃダメ」とか言われてないかとか調べて、使ってもオーケーならファイルハンドルを渡します。
プログラムはファイルを使い終わったら OS に「終わったよー」と申請してクローズします。

http://q.hatena.ne.jp


DQNEOさんのコメント
なるほど。プログラムが直接HDDにアクセスすることはないと。OSに「ファイルオープン」を依頼してるだけだと。 しかしオープンの際のHDDの動作は謎のままですね。 あと、ファイルハンドルの正体は何でしょうか?

4 ● papavolvol
●16ポイント

コンピュータの世界ではレイヤーという考え方が基本にあります。

  1. 物理レイヤー
  2. BIOS
  3. OS (Windowsなど)
  4. アプリケーション

このレイヤーをごっちゃにしてコンピュータを理解することはできません。

例えば「ファイルを開く」はOSがデバイスドライバを使って下層のBIOSにデータの読み出しを指示します。BIOSは物理レイヤーからデータを取り出して上層のOSに返します。OSはもらったデータを上層のアプリケーションレイヤーに渡します。という手順になります。
OSには、ファイルシステムという仕組みがあります。WindowsではNTFSなどがファイルシステムです。これはファイルの目次情報と、ディスク上のデータのアドレスの番地情報の橋渡しをします。ディスク上では単なる01の磁気ですが、ファイルシステムによってファイルごとの意味のある情報になり、BIOSからOSに渡されてファイルという論理的な情報になります。

http://blog.livedoor.jp/papavolvol/
URLは私のブログです。今回の回答と直接の関連ではありませんが、ご縁がありましたら一度お越しくださいね。


monyoさんのコメント
細かい話ですが、Windowsなど現在のOSではBIOSはOS起動時以外使いません(使えません)。大筋は書かれたとおりであってますが。Microsoft系でいうと、起動時以外もBIOSを使っていたのはMS-DOSが最後だと思います(Windows 9x系がどっちだったか…)。

DQNEOさんのコメント
ありがとうございます。 誤:BISO →正:ドライバ と読み替えればよいでしょうか。 レイヤになってるのは理解しました。 しかし、「開く」=「読み出しを指示します」は変じゃないでしょうか。 openとreadは別ですよね。 私の質問は、「読む」は直感的に理解できるが、「開く」は何か?です。

monyoさんのコメント
たとえば、ファーストフードのお店にいって、いくつかハンバーガーを買おうと思って列に並ぶという行為を想定したとき、ハンバーガを1つ頼むたびにお金を払って、また列に並びなおして、2つ目のハンバーガを買って……とはしないですよね。 +列に並んで、店員さんと対面?する(open) +ものをいくつか買う(read/write ※この例だと店から買うだけなので、一方向ですがたとえ話ということでご容赦を) +最後に決済して注文したものをもらう(close) といったノリになると思います。 もう少しコンピュータ的にいうと、読み出す前に、読み書きの間に別のユーザやプロセスがそのファイルを使えないようにするロック処理、ユーザから指定されたファイル名と、ファイルシステム上のファイルIDとの対応付けを行ったうえで、一時受け渡し用の領域を整備したり、アクセス権のチェックを行ったりという処理が入ります。 これをread/writeの度に行うこともできますが、前作業のオーバーヘッドが大きい、もしくは一連の書き込みを行うまで、他のプロセスから書き込みを入れさせたくないといったことがあるので、一連のread/writeの前に一度openという形で行い、一連のread/writeの完了時点で領域の開放(close)という処理を行うのが一般的ですという話です。 ファイルハンドルは、それらの一時的な管理情報を示すタグであると考えればよいでしょう。 なお、別のところでも書いたように、現在のソフトウェアは何層にもわたった階層構造になっていますので、アプリケーションがハードディスクにどのようにかかれるかを意識することはできませんし、その必要もありません。

DQNEOさんのコメント
なるほど。 プログラム⇔OS間でのopen/closeは、例えば、PHP⇔MySQL間でのconnect, closeのようなものと考えればよいでしょうか。セッション開始とセッション終了のようなものであると。 ハンバーガー屋さんの例は大変わかりやすいですね! ありがとうございます。

monyoさんのコメント
セッション開始と終了のようなもの、という理解でよいと思います。 なお、どこかのコメントで、わざわざ「fopenでいうopenの場合」みたいな断りを入れましたが、セッションや開始、終了という概念は、いろんなレイヤで使われます。ファイルのオープンからクローズまでの一連の流れもセッションと捉えることもできますし、逆にconnect-closeを、セッションのオープン、セッションのクローズという表現で記載することもできます。

5 ● Baku7770
●16ポイント

コンピュータの中でOPEN、CLOSEと言われると確かに現在ではイメージしづらいかも知れません。
元々の発想や、旧来のコンピュータを考えると逆にイメージしやすいと考えます。
ファイルってご存知ですかね。コンピュータのではありません。キングやコクヨといった事務用品メーカの作っているファイルです。後、フォルダも。

キングジム キングファイルG A4タテ500枚 グレー 975GX

キングジム キングファイルG A4タテ500枚 グレー 975GX

A4-SIF-B 個別フォルダーエコノミータイプA4青10冊入

A4-SIF-B 個別フォルダーエコノミータイプA4青10冊入

コンピュータの黎明期というか、ノイマン以前の事務機械ってファイルとかバインダといった紙書類の保管システムの更新として期待されていたものですから、その当時の用語が残っています。
さらに初期のコンピュータだとメモリやDASDといった外部記憶媒体の容量が小さかったから差替えながら使っていましたからね。用語をそのまま使っていても違和感を感じなかったのでしょう。
実際にファイルをOpenするということは、パソコンだとFATなどを参照してハードディスク上のデータを特定してメモリに展開する。closeはメモリのロックを外して開放するといった動作になります。
http://support.microsoft.com/kb/100108/ja


DQNEOさんのコメント
「パソコンだとFATなどを参照してハードディスク上のデータを特定してメモリに展開する。」 何をメモリに展開するのでしょうか? これは、readの説明に見えます。 紙ファイルを「開く」ときは、紙ファイルそのものの形状が変わりますよね。 HDD上のファイルを「開く」とき、HDDそのものは変化するのでしょうか?

1-5件表示/13件
4.前の5件|次5件6.
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ