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


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

では、開く、閉じるは?

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

しかし、C言語などで

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

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

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

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:
  • 終了:2011/12/10 00:40:04
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答13件)

id:kodairabase No.1

回答回数661ベストアンサー獲得回数80

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

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

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

他3件のコメントを見る
id:DQNEO

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

2011/12/04 08:05:25
id:tazikisai-mukou

『「開く」と「読む」は違うと思ったのですが。』確かに違います、回答者の文を読めばそう言う理解にならないと思いますが。

紙製の「ノート」をイメージしてみて下さい。
ノートを開く事、つまり「読み書き」する為の準備が「開く」です。
「開いた」あと、書き込まれた事を「読んだり」「書き込みを修正したり」「新たに書き加えたり」「消す事」ができます。
「閉じる」は「読み書き」作業が終了した後、「読み書き」できない状態にすることです。
コンピュタのメモリーの場合、読み書き(書き換え・消去を含む)のできるものをRWM、読むことだけ出来るものをROMといいます。(1度だけ、書き込みができるものもありますが)そこが「紙製」と少し違いが有りますが、兎に角「開く」「閉じる」の概念は共通です。


既に印刷された本などは、「開いて」も基本的には内容を「読む事」だけできます、「消去・修正・追加書き込み」はできません。もっとも、行間にメモや塗りつぶしはできますが。

2011/12/05 13:01:39
id:hirokiky No.2

回答回数1ベストアンサー獲得回数0

ポイント16pt

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

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

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

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

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

id:DQNEO

なるほどなるほど。すごい難しいですね。
でもちょっと答えに近づいた気がします。
ありがとうございます!

2011/12/03 03:48:17
id:HowAreYou No.3

回答回数91ベストアンサー獲得回数17

ポイント16pt

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

http://q.hatena.ne.jp

id:DQNEO

なるほど。プログラムが直接HDDにアクセスすることはないと。OSに「ファイルオープン」を依頼してるだけだと。

しかしオープンの際のHDDの動作は謎のままですね。
あと、ファイルハンドルの正体は何でしょうか?

2011/12/04 08:08:35
id:papavolvol No.4

回答回数1078ベストアンサー獲得回数199スマートフォンから投稿

ポイント16pt

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

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

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

  • まずディスクの磁気やチップの電荷などは物理レイヤーです。それぞれにドライバやファームなどの制御の仕組みが働いています。
  • それをコントロールするのはBIOSというプログラムです。BIOSは、物理レイヤーと論理レイヤーの橋渡しをします。
  • 論理レイヤーの最下層には、Windows やリナックス、サーバーならUnix、大型機ならZ-OS などのOSが稼働しています。OSは自分のデバイスドライバというプログラムを使って下層のBIOSと連携し、上層のアプリケーションレイヤーとの橋渡しをします。

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

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

他3件のコメントを見る
id:DQNEO

なるほど。
プログラム⇔OS間でのopen/closeは、例えば、PHP⇔MySQL間でのconnect, closeのようなものと考えればよいでしょうか。セッション開始とセッション終了のようなものであると。

ハンバーガー屋さんの例は大変わかりやすいですね!
ありがとうございます。

2011/12/04 22:15:31
id:monyot

セッション開始と終了のようなもの、という理解でよいと思います。

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

2011/12/04 23:27:16
id:Baku7770 No.5

回答回数2832ベストアンサー獲得回数181

ポイント16pt

 コンピュータの中で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

id:DQNEO

「パソコンだとFATなどを参照してハードディスク上のデータを特定してメモリに展開する。」
何をメモリに展開するのでしょうか?
これは、readの説明に見えます。

紙ファイルを「開く」ときは、紙ファイルそのものの形状が変わりますよね。

HDD上のファイルを「開く」とき、HDDそのものは変化するのでしょうか?

2011/12/04 08:16:52
id:monyot No.6

回答回数146ベストアンサー獲得回数18

ポイント15pt

「概念」として理解したいのであれば、裏側をあまり意識しない方が理解できると思います。

裏側にしても、ハードディスクへの読み書きから順番に理解していくのは相当技術力が必要だと思います。

土地に倉庫を建てるという例でOSあたりを中心に概念的に説明すると。

  • だだっぴろい土地がある状態→未フォーマットのハードディスク
  • 土地を(たとえば)1m四方に区切り、たとえば4行5列目、といったらどこの部分を示すかがわかるようにすること→物理フォーマット
  • OSさんから倉庫(ファイル)をいくつか建てる依頼がくる前提で、個々の倉庫の識別方法や、倉庫の大きさ(たとえば45平米)、IDなどで指示できるように整理し、実際にどこの区画にどういう大きさで立てたかを管理できるように定義すること→論理フォーマット(ファイルシステムの作成)

といった前準備がまず発生します。ついでファイルの作成になりますが、

  1. お客さん(アプリ)が倉庫をこういう倉庫名(ファイル名)で、このくらいの容量(たとえば36平米)の倉庫を建ててほしいと倉庫管理業者(OS)に依頼
  2. 倉庫管理業者は、論理フォーマットの表を元に、ここの区画にこういう形(たとえば4 x 9で)で建ててほしいと倉庫業者(デバイスドライバ)に依頼。3つ目の倉庫なので管理番号は3、倉庫名はお客さんからの指示の名称をつけて管理(倉庫名は変更されることもあるので)、空きスペース36平米といった管理作業を行う。
  3. 倉庫業者は建設業者(ハード)に依頼して倉庫を建てる。

といった作業が発生します。

ファイルをオープンする場合は

  1. お客さんが倉庫名(ファイル名)を指定して、借用している倉庫にものを置きたい。倉庫名はfile1ですと倉庫管理会社に依頼(fopen発行)
  2. 倉庫管理会社が、受付担当者をアサインしました。以降今回の倉庫への搬入はこの担当者にお願いしますと返答(fopenの返答としてfpを返却)
  3. では4平米の荷物をお願いしますと依頼(write)
  4. 受付担当者(OS)は、スペースを確認した上で、荷物を倉庫に置くよう、倉庫業者(デバイスドライバ)に依頼。その際、倉庫名から対応表を使って割り出した倉庫識別番号を渡す。
  5. 倉庫業者は倉庫識別番号と空きスペース情報を元に、倉庫に荷物を持っていく
  6. 建設業者(ハード)は、倉庫内に、たとえば2x2でおくか、4x1で置くかなどを考え、実際に倉庫に荷物を置く。
  7. 引き続き、追加で荷物を置いたり、既存の荷物の搬出を行わない場合は、今回のやりとりの完了をお願いする(fclose)

といった感じになると思います(少し抜けもれあると思いますが)

これらを実際にはプログラムで行うので、プログラムでどう実装されているかはまた別のレベルの理解が必要になります。

URLはダミーです http://www.google.com/

id:DQNEO

なるほど、わかりやすい説明をありがとうございます。
openというのが、「プログラムからOSへの依頼とその返答」であることがよくわかりました。

基本的にopenというのは、プログラム⇔OS の相互作用の話であって、OS⇔物理メディアの相互作用の話ではない、と理解しました。

この理解であってますでしょうか?

2011/12/04 08:22:16
id:monyot

openというのがfopenなどのことであれば、その理解でよいと思います。別のところで、階層構造になっているという話もでていると思いますが、これは言い換えると下の階層の動作が(いい意味で)隠蔽されているということも意味します。

たとえば、郵便を出すときに、その郵便物がどうやって相手の手元に届くかは理解していなくても郵便を出す、期日を指定するといったことが可能なのと似ています。

わたしの例で言うと、たとえば4平米の荷物を置いてくださいという指示の際に、お客さんは、どこの区画にどうおくかは意識する必要ないし、できないということです。

2011/12/04 12:37:28
id:pmakino No.7

回答回数358ベストアンサー獲得回数30

ポイント15pt

アプリケーションのファイル要求に対して裏側でどのようなことが行われているかを知るには、OS が提供する機能の一部であるファイルシステムについて学ぶ必要があります。
まずはファイルシステム - Wikipedia を、さらに深く知るならファイルシステムでググるのが良いと思います。

id:DQNEO

なるほど、ファイルシステムについて勉強すればよいのですね。
つまり、「私はファイルシステムをわかっていない」ということがわかりました。

これは大きな一歩です。
ありがとうございました。

2011/12/04 08:23:25
id:flashrod No.8

回答回数31ベストアンサー獲得回数3

ポイント15pt

昔は「ファイル」なんて便利なものはなくて、ディスクのトラックやセクタを番号で指定して読み書きしていたんですよ。読み書き、とは補助記憶装置と主記憶との間でバイト列をやりとりすることです。
http://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%82%BB%E3%82%AF%E3%82%BF

でもそれだとディスクを読み書きするプログラムがどのセクタに何のデータを格納するかきめなくちゃいけないし、いろいろめんどくさいので、「ファイル」という考え方を賢い人が思いついたわけです。ファイルの中身はバイト列にすぎないわけだけど、そのバイト列がディスクのどのトラックのどのセクタに格納されているか、なんてのはファイルを読み書きする側からは知らなくてよい、そういうのはファイルシステムが全部めんどうをみてくれるわけです。

そのファイルシステムとアプリケーションプログラムとの間でおこなう取り決めとして、「ファイル名」という名前を使って「開く」ことでファイルを掴む「ハンドル」を得て「読み書きする」、もう使わなくなったら「閉じ」て、掴んでいたハンドルを開放する、というアクセスの手段が「ファイルを開く」ということです。

他1件のコメントを見る
id:flashrod

ふつう大きなファイルなら二つ以上のセクタに格納されていますからハンドルとセクタがそんな単純に対応づいたりはしないです。このファイルはディスク上のどこからどこまで使っている、などというのをファイルシステムが管理しています。
ハンドルを開放しなければならないのは、ファイルアクセスがコンピュータにとって非常に重くて遅い仕事だっていう感じを持てばわかると思います。ディスク上にファイルを大量につくっておくことはできても、ファイルを本当に同時に読み書きできるのはせいぜい数個にすぎません。だから、いまからこのファイルを読み書きしますよ、と言って開いて、もう読み書きしませんと言って閉じるわけです。そうしないと誰かがファイルを読み書きしていると他の人がファイルを読み書きできなくなります。そのもうアクセスしませんと言うのがファイルを閉じるでありハンドルを開放するということです。

2011/12/04 16:22:53
id:DQNEO

そうすると、ハンドルを獲得するというのは、読み書きする権利を獲得すること、ハンドルを開放するとうのは、その権利を手放すこと、ということになるんですかね。ちょっとイメージがわいてきました。

2011/12/04 22:27:20
id:kokorohamoe No.9

回答回数27ベストアンサー獲得回数2

ポイント15pt

http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

OSはディスクに対して0か1かをビット単位で直接アクセスすることは稀です。
一般的には
アプリケーション <> OS <> ディスク <> 物理的な円盤 という通信を行います。 
この時 ディスク <> 円盤 の間では0 1 の通信が行われます。
OS <> ディスク の間では セクタやクラスタ といった ある一定の0と1の集合単位で操作をします。これは、0や1しかない通信で 何十バイトも通信をすると非効率なので まとめて通信しよう ということから セクタ クラスタ という考え方が生まれました。
さて、アプリケーション <> ディスク ですが
たとえば、物を書きこむときに ディスクの先頭から数えて 何クラスタ目の何セクタ目にXを書き込む と指定するのは 毎回毎回 すべてのデーターで ディスクの先頭から数えていかないといけないので、覚えておくのが大変です。
 
そこで、アプリケーション <> OS <> ディスク
と中間にOSが入り ファイル という仮想的な単位を見せてくれます。
こうすることによって アプリケーションは ディスクの先頭からXセクタ目 という事を いうのではなく XXという名前のファイルの先頭からXバイト目という指定をできることになります。
 
OSは この ファイル名とその先頭から数えて何バイト目という信号を ディスクの先頭から数えてXクラスタ目のXセクタ目のXバイト目という信号に書き換えます。
つまり、通訳をしています。
これをファイルシステムと呼びます。
 
OSはファイルオープンと呼ばれると ファイルシステムから ファイルの先頭がディスクの先頭から数えて何クラスタ・セクタ・バイト目なのか?という相関関係の表を読み出します。 クロースを呼ばれると、この相関関係の表をメモリーから捨てます。
 
要するにファイルのオープン・クローズとは この相関関係の表を読み出せ・捨てろという事です。

他にもこのオープン・クローズはバッファリングなどいろいろなアプリケーションにとって有利なことをします。
相関関係の表はWindowsであればFATやNTFS Linuxであればext3 などが有名です。
 
その他アプリケーションが オープン・クローズ と 読んでいるのは この歴史的なファイルシステムのオープン・クローズ から 由来している名前であり 一意な定義は ありません。 アプリケーション固有の動作となります。
しかし、一般的に OSのファイルシステムの オープン・クローズ を呼んでいる という動作は 同じだと思います。
 
また、厳密なオープン時 クローズ時の動作は OSにより若干異なりますが概念的には 上記です。
 
なぜ、ディスクの先頭から数えないのか?というのは、毎回毎回ディスクの先頭から数えているのは面倒だからと思うプログラマーが多く ファイルシステムのほうが人気だったから。という歴史的経緯です。
もし、人間の頭が機械のように暗記に長けていて、とんでもなく長い数列を暗記可能でディスクの先頭からを覚えるほうが楽であればファイルシステムはなかったかもしれません。

総合的な回答としては、歴史的経緯でプログラマにファイルシステムという物が人気で使われており、その時の処理の名前にたまたま 比較的処理をイメージしやすいOpen,Closeという名前がついた。ということで
Open,Closeとは上記のような処理についた名前である。というのが回答になります。

以上です。

他1件のコメントを見る
id:monyot

fopenというレイヤのopenであれば、大雑把に言えば、プログラムとOS間の処理ですね。

最も、fopenは少し皮をかぶせていて、もう少し低レベルなopenであれば、openという関数を呼び出すこともできます。

様は、最近のソフトウェアは何層にも階層化されていて、基本的にはその下のことは意識する必要もないし、基本できないということに尽きます。

たとえば、openの延長上で、ディスクに何か操作を行うか、メモリ上で完結させるかはOSが適宜判断することであって、openを呼び出すアプリケーションが意識する必要はないということです。

たとえば、RAMDISKであれば、read/writeも含めてすべてメモリ上で完結しますが、アプリケーションは呼び出し先がRAMDISKか、ハードディスクか、はたまたUSBメモリかといったことを意識して操作方法を変えたりすることはないということです。

2011/12/04 12:54:10
id:DQNEO

そうすると、open時にOS⇔HDD間でなんらかのやりとりが発生してるかもしれないが、それはプログラマにとっては隠ぺいされていて、知る必要はないし知ることもできないと。
また謎が深まりました。

確かにRAMDISKだと全てメモリ上の話ですね。

2011/12/04 22:30:21
id:kokorohamoe No.10

回答回数27ベストアンサー獲得回数2

ポイント15pt

(ポイント不要 話題が長いので別途書いておきます。)
はい。基本的にOpen,CloseとはOSが提供する機能であって、ディスクが提供する機能ではありません。
ただし ファイルシステムはディスクを使って実現されているので 完全にメモリだけで実現されているわけではありません。相関関係の表=ファイルテーブルはディスク上に書かれています。
しかし、一般的には OSが提供する機能とりかいして問題ありません。

http://ja.wikipedia.org/wiki/%E7%A3%81%E6%B0%97%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E8%A3%85%E7%BD%AE
ディスク=磁気ディスク装置(以後 ディスクシステム)の事です。略してしまってすみません。
HDDの中には複数または1枚の円盤が入っています。
ディスクシステムはPCとのインターフェイス
BIOSのような ディスクシステムのOS
円盤絵の書き込み装置
円盤
からなっています。
 
アプリケーションから直接円盤に書きこもうとすると とんでもなく複雑な知識が必要になるため(円盤の回転数や電圧などを管理したくないですよね?)
ディスクシステム側で クラスタやセクタなど 便利な機能を提供し
それを OSがデバイスドライバ経由で利用し OS は アプリケーションに ファイル という便利な機能を提供しています。

id:kokorohamoe

あ、自分の回答に作者さん以外がコメントできるんですね。すみません、知りませんでした。連投になってすみません。

2011/12/04 13:51:36
id:DQNEO

たしかに、HDD=円盤ではなくて、HDDの中も階層構造になってますね。円盤の枚数と回転とか意識したことはありません。

「Open,CloseとはOSが提供する機能であって、ディスクが提供する機能ではない」
この一言に尽きると思いました。

ありがとうございます!

2011/12/04 22:31:56
id:nmori No.11

回答回数76ベストアンサー獲得回数9

ポイント15pt

ファイル(ディスク上のものも仮想のものも)はメモリに読み込む必要があります。
そのメモリ上の場所を示すのがファイルポインタ(orハンドル)で、多くの言語ではファイルのオープン時に変数として割り当てられます。「この"text.txt"ってファイルを開いてよ」という依頼に対し、「じゃぁ、このfpっていう変数が指している場所に読み込んでやるよ」と教えてくれるわけです。

多くの場合、読み書きが終わるとファイルを読み込むためのメモリ領域が不要になりますし、(ディスクなど)アクセス競合の管理があるメディアの場合は「もう使わないよ」と宣言してもらう必要があったり、必要がないにしても、並行に実行されている他の処理がスムーズに進む場合があります。プログラム内でクローズするとそのようなことが(必要なら)行われます。

URLはダミーです。
http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

id:sibazyun No.12

回答回数1824ベストアンサー獲得回数246

ポイント15pt

あえて、質問者の最初の問題提起にそって述べます。

・ファイル読み取りは、【ディスク内のデータ領域のある特定のアドレスの】これらの1,0の並びを認識すること
・ファイル書き込みは、【ディスク内のデータ領域のある特定のアドレスの】これらの並びを変更すること

ですが、では、そのアドレスはどうやってディスク装置が知ることができるか、です。なにしろ、ユーザはファイル名しか与えていないからです。

で、ディスク内には、ディレクトリ領域というのがあって、そこに「ファイル名とアドレスの対応表を格納することができます。まだ対応ができていない(新規書き込み)なら対応表を作ります。すでにあるときには、その対応表を読みます」。これは物理的には、ディレクトリ情報(ファイル名、アドレス、書き込み権利など)が、0,1で構成される文字情報、数字情報なので、それらの0,1情報を読んだり書いたりしています。つまりディスク本体では、オープンやクローズでは、ディレクトリ領域に対する読み書きが発生しています。

 で、ディレクトリ領域がどこにあるかというと、それはいわゆるOSが知っているわけですが、そのOSというのも、ほとんどの場合Disk OSなので、ディスク内のOS領域に対して読み書きしています。

 もちろん、オープン、クローズは主記憶内でもいろいろなことをやっていますが、ディスクへの物理的なアクセスは発生しています(それを仮想ディスクであるメモリ空間であるとか、細かくいえばありますが、おおざっぱな認識として)。

ダミー:http://q.hatena.ne.jp/answer

●追記: ついでにいうと、「ファイル削除」は、決して、「データ領域のビットを全て0で埋め尽くす」ということでなく、ディレクトリ領域の対応表を消すことです。したがって、実際のディスクのアドレスは、別のファイルによって再利用されるかもしれないし、再利用されないで、元のデータが残っているかもしれない、です。

id:DQNEO

ふむふむ。
オープン時のコンピュータ内の動きが少しイメージできました。

しかし、「プログラムからは、ディスク本体の動きは知ることはできない」という意見と対立しますね。

「ファイル名とアドレスの対応表」というのが鍵のようですね。
これが、ファイルシステムということなのでしょうか。

2011/12/09 07:03:08
id:sibazyun

「プログラムからは、ディスク本体の動きは知ることはできない」ですが、
それが上位の、fopenを記してあるメイン・プログラムということなら、
ディスクの実アドレスは知りません。fopenの引数で実アドレスを
引いて、それをfwriteに渡してはいません。しかし、下位では知っています。
ちょうど、下記コメントに書いた社長(?)と秘書の文書格納の比ゆでいえば、
社長は文書が格納されている棚の書類ファイルのありかを知らない(関心がない)
のと同じです。

 なお、簡単のため、「ファイルの先頭アドレス」のように書きましたが、
長いデータは、ディスク上の連続したアドレスに格納されるとはかぎらず、
レコード単位に別々に格納されていますが、では、次のレコードはどこか、
といったことまでファイルシステムは管理しています。

2011/12/09 09:09:55
id:rascal_k2 No.13

回答回数3ベストアンサー獲得回数0

ポイント15pt

既に色々な方の回答もありますので、ちょっと違う観点からの回答とします。
自分もC言語を勉強し始めの頃は、同じような疑問を持ちました。
自分の経験を踏まえて考えますと、コンピュータを勉強し始めの頃は、
シンプルなモデル上で、プログラムをイメージしていたように思います。
メモリ上には、自分のプログラムだけが配置され、入出力機能も独占しているような状態。
であれば、やりたい事が、ディスクへの書き込みであれば、
何故に、直接、ディスクへ書き込んでくれないの?といった感じです。
初期のコンピュータでは、きっと、直接書き込んでいたように思います。
でも、みなさんが説明して頂いているように、低レベルでの読み書きは、
実は、色々と面倒な手順を踏まないといけないんですね。
「こんなの毎回やってられね~よ。
 ファイル名指定するだけで、後は書き込みたいデータだけ渡せば、
 (もしくは読み込みたい領域を指定すれば)
 面倒な事は代わりに誰かやってくれ~!!」
そんなこんなでOSが登場するわけです。
現在のOSは、色々と芸達者で、規模も大きくなっていますが、
ここでの説明では、便利なサブルーチンの集合とでも捉えて下さい。
で、まぁ、ディスク読み書き用のサブルーチンを用意してもらったので、
今までの面倒な作業をする代わりに、
読み書きする前にサブルーチン(f)openを呼び出すと、
OSは読み書きに必要な物をあれこれと用意してくれます。
ファイルポインタやファイルハンドルといった物は、
その必要な物のあれやこれやを参照する為の物です。
その後、(f)readや(f)writeなどで、好きに読み書きを依頼すれば、
OSが責任を持って面倒な作業を肩代わりしてくれます。
また、OSは、調停役であり監視役でもありますので、
他のプログラムとの兼ね合いやら権限のチェックやら、
もしくはシステム全体の効率なども踏まえて、
適切と思われるタイミングで物理的な読み書きを実行します。
そのような理由もあって、依頼した内容が、即反映されるとは限りませんが、
基本的にはOSが帳尻を合わせてくれます。(電源ぶち切りとかしなければ)
で、最後に、読み書きが終了した時点で、(f)closeを呼び出すと、
OSは、あれこれと用意した物を、綺麗に片付けます。
これを忘れると、OSは、まだ読み書きを続けるつもりで、
あれこれと必要な物を残したままにしておきます。
昔、新米プログラマの時、closeを忘れ、
メモリ不足でアプリが落ちた苦い経験がありますが、
きっと、多分、そのような経験を重ねる事で、
コンピュータの内部の動きが実感出来るような気もしますので、
たくさん書いて、たくさん動かしてみる、というのも大事かな、なんて思います。
http://d.hatena.ne.jp/rascal_k2/

id:DQNEO

なるほどなるほど!

「新米プログラマの時、closeを忘れ、
メモリ不足でアプリが落ちた苦い経験がありますが、
きっと、多分、そのような経験を重ねる事で、
コンピュータの内部の動きが実感出来る」

非常に実践的なアドバイスですね!
苦労する、痛い目を見る、というのがポイントですね。
すごく腑に落ちました。

ありがとうございます!

2011/12/09 07:07:11
  • id:seble
    乱暴、単純に言っちゃうと、ここで言うファイルオープンは
    HD等の記録メディアからデータをメインメモリ(もしくはキャッシュドライブ)に展開し、(メモリ上で)osやらアプリで操作できる状態にする事。
    でいいんじゃないの?
    HDの方は、読み出しただけだからもちろんそのまま、書き込みされて初めてデータが変更される。
  • id:TransFreeBSD
    ちょっと横道にそれるけど、ファイルといってもHDD上だけじゃないし、ディスク上とも限らないし、物理的なものとも限らないです。
    #ttyとかNFSとか/proc以下とか
    ファイルハンドルがあると何かと便利だから、でいいように思う。
    #セッションクッキーが近い?
  • id:DQNEO
    > 「HD等の記録メディアからデータをメインメモリ(もしくはキャッシュドライブ)に展開」
    これも、readの説明な気がします。

    > ファイルといってもHDD上だけじゃないし、ディスク上とも限らないし、物理的なものとも限らないです。

    USBメモリとかSDカードにもファイルは置けるので、HDDだけじゃないのは理解しています。

    結局、open時に(HDD/USBメモリ/SDカード)はどう動くのか?というのが疑問なのです。


  • id:DQNEO
    結局、「開く」「閉じる」という命名が、いらぬ誤解を招いてる気がしました。

    紙ファイルを開いたり閉じたりする場合、紙ファイルそのものがパタパタと動きます。
    この連想から、コンピュータのオープン・クローズはHDD内で何が動いてるのか?と考えてしまいました。

    もしこの処理の名前が "open,close" ではなく "begin, end"とかだったら、もうちょっと違う角度から考えたかもしれません。

    とりあえず、ファイルシステムについて勉強しようと思います。


  • id:DQNEO
    あとは反省点として、

    echo "hello" > hello.txt
    が「HDDへの書き込みである」という理解が短絡的でした。

    ミクロ的には、①書き込み用オープン、②書き込み、③クローズ、の3つの処理が行われていますね。
  • id:TransFreeBSD
    > USBメモリとかSDカードにもファイルは置けるので、HDDだけじゃないのは理解しています。
    他にプリンタや画面出力もファイルとして扱います。
    linuxだと /proc/cpuinfo というファイル(として扱えるもの)でCPUの情報が取得できます。
    これらも open, close で扱います。ま、横道なんですけど。
    monyoさんのが分かりやすいかなと思いました。整理券とかチケットを発行する手続きの様なものかな。
  • id:DQNEO
    冒頭の質問の「ファイルを開く」は、あくまでC/PHP/Perl などからfopenすることを指していました。
    Excelなどのアプリの「ファイルを開く」についての質問ではありません。(これはopen + read)

    説明不足ですいませんでした。

    プログラム⇔OS間でのopen,read, write, close,とは、
    PHP⇔MySQL間でのconnect, select, insert, closeのようなものというイメージがわいてきました。

    もしくは、open/closeはTCPでいうところのコネクション確立・切断みたいなものと考えればいいんですかね。
  • id:DQNEO
    わかったこと:

    「読む」「書く」は、そもそもファイルを開かないとできない。
    ファイルを開くことなしに「読む」は成り立たない。
    つまり、私は「読む」「書く」を本当の意味で理解していなかった。

    下記の認識が間違っていた。

    「・ファイル読み取りは、これらの1,0の並びを認識すること
     ・ファイル書き込みは、これらの並びを変更すること」

    ファイルの話と、1,0の並びの話は全くレイヤが異なる。
    ファイルを開く・読むとは、プログラム⇔OS間のファイルシステム処理についての話であって、物理メディア上での処理の話ではない。
    よってそのとき物理メディアがどう動くかはプログラムからは隠蔽されているので、知ることはできない。

    結論:
    私は、「開く」「読む」「書く」「閉じる」全部ひっくるめて、ファイルシステムを理解してないので勉強する必要がある。

  • id:sibazyun
    こちらの比ゆでは。。。
    「紙ファイルを開いたり閉じたりする場合、紙ファイルそのものがパタパタと動きます。」

    あなたは秘書で、ある標題の文書を、適切な紙ファイルに綴じることを命じられたとします。
    では、書棚のどこにある紙ファイルに綴じればよいのでしょう。
    それは、書棚の端にある「目録ファイル」をあけて調べます。
    新規文書なら、「目録ファイル」に書き込みます。

    これが、回答12でいう、「ディレクトリ」の比ゆです。
  • id:hissssa
    >私は、「開く」「読む」「書く」「閉じる」全部ひっくるめて、ファイルシステムを理解してないので勉強する必要がある。

    「勉強する必要」はないと思いますが・・・。
    既に議論されているように、ファイル操作はOSレベルの話であってディスク自体の物理層の動きとは別の話です。物理層の動きはOSによって隠蔽されユーザからは見えなくなっていますが、それは「ユーザは知る必要がない」からこそ隠蔽されているわけで。
    興味を持って勉強する事は大いに結構だと思いますが、デバイスドライバを書くようなプログラマになりたいのでない限り、そこまで正確に知る必要はないと思います。
  • id:DQNEO
    せめて、「何がわかってないのか」がわかるようになりたいのです。
    今はまだ、何がわからないのかが分からない状態です。
  • id:DQNEO
    追記:最近システムコールというものについて勉強し始めたら、前よりはわかるようになってきました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません