Filesystem
Library Design
Introduction
Requirements
Realities
Rationale
Abandoned_Designs
References
Filesystem Library として始めることになった最初のきかっけは、Boost 管理ツールとしての失敗からであった。いくつものスクリプトは Python, Perl, Bash と Windows コマンド記述言語によって書かれていた。それらはただ 1 つのありふれたスクリプト言語でなかったため、全ての Boost 管理者たちに受け入れられた。すでに彼らは C++ プログラマとしてのスキルをもった人たちであったが、なぜ C++ はスクリプト言語として使われなかったのか?
The primary motivation for beginning work on the Filesystem Library was
frustration with Boost administrative tools. Scripts were written in
Python, Perl, Bash, and Windows command languages. There was no single
scripting language familiar and acceptable to all Boost administrators. Yet they
were all skilled C++ programmers - why couldn't C++ be used as the scripting
language?
C++ の将来像はスクリプトのようなアプリケーションに不可欠であるディレクトリなどを含んだ移植性のあるファイルシステム操作ができることである。Filesystem Library は、それらをみたすものとして開発された。
The key feature C++ lacked for script-like applications was the ability to
perform portable filesystem operations on directories and their contents. The
Filesystem Library was developed to fill that void.
目的は伝統的なスクリプト言語に匹敵することではなかったが、C++ をいつも言語の選択肢としてあげる機会をもたらした。
The intent is not to compete with traditional scripting languages, but to
provide a solution for situations where C++ is already the language
of choice..
- 現在の C++ で移植可能なスクリプトスタイルのファイルシステム操作を書けるようになること。
論理的根拠: これはプログラミングに必要な共通なものである。それは、今日の C++ あるいは Boost ライブラリのどちらでも実現できない困惑と苦難である。必要なものは C++ がツール群で唯一のツールセットとなるとき、とりわけ深刻なことである。ファイルシステム操作は何らかの言語で提供されている。いくらかのプラットフォーム上で特定のスクリプト言語と同様に Perl や Python のような、いくらかのプラットフォーム上で使えるものがそうだ。全てのオペレーティングシステムはファイル操作を API のような形で提供したり、POSIX 連合は Mac, z/OS, OS/390 のような POSIX に普通は関連のないオペレーティングシステム上で可能にしてくれるものが増えている。
- Be able to write portable script-style filesystem operations in modern
C++.
Rationale: This is a common programming need. It is both an
embarrassment and a hardship that this is not possible with either the current
C++ or Boost libraries. The need is particularly acute
when C++ is the only toolset allowed in the tool chain. File system
operations are provided by many languages used on multiple platforms,
such as Perl and Python, as well as by many platform specific scripting
languages. All operating systems provide some form of API for filesystem
operations, and the POSIX bindings are increasingly available even on
operating systems not normally associated with POSIX, such as the Mac, z/OS,
or OS/390.
- 成果は、下記の realities で示したものになること。
論理的根拠: これは研究プロジェクトではない。今日のプラットフォーム上で必要なことは、制限されたファイルシステムを使ったいくつかの組み込みオペレーティングシステムが含まれていることである。移植性を強調するために、もし標準化されればそのようなライブラリははるかに有用である。このことは、ちょうど Unix あるいは Windows やそれらのクローンたちのプラットフォームとの間でより幅広い成果をあげることができることを意味している。
- Work within the realities described below.
Rationale: This isn't a research project. The need is for something that works on
today's platforms, including some of the embedded operating systems
with limited file systems. Because of the emphasis on portability, such a
library would be much more useful if standardized. That means being able to
work with a much wider range of platforms that just Unix or Windows and their
clones.
- 危険なプログラミングのやり方をしないようにする。特に無視するとても簡単な全てのエラー通知やグローバル変数を使うことである。これは、危険な将来を与えるかもしれないことを分かっておくこと。
論理的根拠: 通常いつもの Boost 要求仕様に含まれている。 しかし、それは同等のネイティブなプラットフォームや無視するとても簡単な全てのエラー通知や現在作業しているディレクトリのようなグローバル変数をまれに依存しているインターフェースのスクリプト言語のために、明確に言及されている。
- Avoid dangerous programming practices. Particularly, all-too-easy-to-ignore error notifications
and use of global variables. If a dangerous feature is provided, identify it as such.
Rationale: Normally this would be covered by "the usual Boost requirements...",
but it is mentioned explicitly because the equivalent native platform and
scripting language interfaces often depend on all-too-easy-to-ignore error
notifications and global variables like "current
working directory".
- ライブラリの構造がたとえいくつかの機能性が与えられたプラットフォームあるいはディレクトリツリーの上で綿密に計画できないものでも、いまだに有用である。特にもっと有益な機能性はフラットな(階層的でない)ファイルシステムにさえ移植性のあるものに違いないこと。
論理的根拠: 階層的なディレクトリ構造を必要としないいくつかの機能性は、フラット構造のファイルシステムでは未だ有用なものである。それらは、特にとても機能性が制限されているような組み込みシステムにおいて未だ有用である。
- Structure the library so that it is still useful even if some functionality
does not map well onto a given platform or directory tree. Particularly, much
useful functionality should be portable even to flat
(non-hierarchical) filesystems.
Rationale: Much functionality which does not
require a hierarchical directory structure is still useful on flat-structure
filesystems. There are many systems, particularly embedded systems,
where even very limited functionality is still useful.
- インターフェイスは、今日の C++ 標準ライブラリ入出力が熟練されてきている。例えば、ファイルのパス名は std::basic_fstream コンストラクタを使うことで簡単にすべきである。
論理的根拠: 最も一般的なファイルシステムの機能性の一つは、起こりうる入出力操作上で使うためのパスを巧みに扱うことである。従って入出力標準ライブラリによってインターフェースが滑らかになる必要がある。
- Interface smoothly with current C++ Standard Library input/output
facilities. For example, file paths should be
easy to use in std::basic_fstream constructors.
Rationale: One of the most common uses of file system functionality is to
manipulate paths for eventual use in input/output operations.
Thus the need to interface smoothly with standard library I/O.
- 標準化の終局にとって好都合である。必要な要求仕様は、最小限に閉じたインターフェースと移植性に関してすばらしい配慮をすること。
論理的根拠: ファイルシステム操作に欠けているものは、欠点を埋めるための候補者たちに知らせるものがないことに受けて現在の標準化の上で重大な欠点となっている。念入りなインターフェースと仕様書の移植が難しいライブラリは標準化に賛同するようなことは、はるかに少ない。
- Suitable for eventual standardization. The implication of this requirement
is that the interface be close to minimal, and that great care be take
regarding portability.
Rationale: The lack of file system operations is a serious hole
in the current standard, with no other known candidates to fill that hole.
Libraries with elaborate interfaces and difficult to port specifications are much less likely to be accepted for
standardization.
- 通常の Boost 要求仕様とガイドラインでは適用されていること。
- The usual Boost requirements and
guidelines apply.
- 必要としなくてもパス名の移植性を刺激すること。
論理的根拠: パスの点で、ユーザが移植性のあるパス形式を必要とするために不条理な入力することから生じる。
- Encourage, but do not require, portability in path names.
Rationale: For paths which originate from user input it is unreasonable to
require portable path syntax.
- 存在しない事実を元にした移植性を移植性として錯覚すること。
論理的根拠: 重要な振る舞いを指定しないことあるいは実装で定義されtないことは、プログラマーたちがコードをあてにした振る舞いが移植性のあるものだとあらわしたライブラリを使うことは大きな損害であるし、実際それは移植性がない。標準化の段階で賛成することは、ユーザたちと実装する人たちが他の資源からどんな振る舞いを正確に知っているときといったたった1つのケースで必要とされるが、何らかの理由でそれを正確に特定することは可能ではない。
- Avoid giving the illusion of portability where portability in fact does not
exist.
Rationale: Leaving important behavior unspecified or "implementation defined" does a
great disservice to programmers using a library because it makes it appear
that code relying on the behavior is portable, when in fact there is nothing
portable about it. The only case where such under-specification is acceptable is when both users and implementors know from
other sources exactly what behavior is required, yet for some reason it isn't
possible to specify it exactly.
- あるオペレーティングシステムは1つのルートディレクトリツリーをもっているが、複数のルートをもっているものがある。
- Some operating systems have a single directory tree root, others have
multiple roots.
- あるファイルシステムはファイル名の形を長いものと短いものともに用意されている。
- Some file systems provide both a long and short form of filenames.
- あるファイルシステムはファイルのパス名とディレクトリのパス名の異なった形式をもっている。
- Some file systems have different syntax for file paths and directory
paths.
- あるファイルシステムは確実なファイル名と確実なディレクトリ名に対して違った規則をもっている。
- Some file systems have different rules for valid file names and valid
directory names.
- あるファイルシステムはとても制限されたファイル名(8.3 と呼ばれている)を使っている。(例をあげると、ISO-9660 level)
- Some file systems (ISO-9660, level 1, for example) use very restricted
(so-called 8.3) file names.
- あるファイルシステムはディレクトリツリー内部でマウントされた異なった文字を持っているファイルシステムを許可している。例えば ISO-9660 や Windows のファイルシステムは POSIX のディレクトリツリーをサブツリーとして集結させているだろう。
- Some operating systems allow file systems with different
characteristics to be "mounted" within a directory tree. Thus a
ISO-9660 or Windows
file system may end up as a sub-tree of a POSIX directory tree.
- ディレクトリやファイル操作のワイド文字のバージョンはいくらかのオペレーティングシステム上で可能になっているが、不可能なものもある。
- Wide-character versions of directory and file operations are available on some operating
systems, and not available on others.
- ディレクトリ階層はルートから左右にきちんとしているという点で明確でなければならないという規則はありません。
- There is no law that says directory hierarchies have to be specified in
terms of left-to-right decent from the root.
- あるファイルシステムは "バージョン番号" あるいは "世代番号" ファイルの考え方をもっている。あるファイルシステムは持っていない。
- Some file systems have a concept of file "version number" or "generation
number". Some don't.
- 全部ではないが、オペレーティングシステムはパス名としてシンプルな文字を区切りとして使っている。あるオペレーティングシステムはペアになった記法を使っている。代表的なものとして OpenVMS のファイル名は次のような形で完全に指定しなければならない。
- Not all operating systems use single character separators in path names. Some use
paired notations. A typical fully-specified OpenVMS filename
might look something like this:
DISK$SCRATCH:[GEORGE.PROJECT1.DAT]BIG_DATA_FILE.NTP;5
一般の OpenVMS フォーマットは
The general OpenVMS format is:
Device:[directories.dot.separated]filename.extension;version_number
- 共通ファイルシステムのために、二つの記述者たちが同じ実態であることは非常に困難であるか不可能であると決められる場合がある。例を挙げるとバランスのとれた考え方はパスの部分的な違いができてしまう。神経質なロケールの場合があるかもしれないが、他のものはない。神経質なケースはパス名自身やプラットフォームではないもののプロパティである。統一されているシーケンスはいっそう悪く限られたものになってしまう。
- For common file systems, determining if two descriptors are for same
entity is extremely difficult or impossible. For example, the concept of
equality can be different for each portion of a path - some portions may be
case or locale sensitive, others not. Case sensitivity is a property of the
pathname itself, and not the platform. Determining collating sequence is even
worse.
- 競争状態を生じさせることがある。ディレクトリツリー、ディレクトリ、ファイルやファイル属性は全てのスレッド、プロセスとファイルシステムにアクセスしているコンピュータとの間に共有されたものとなる。このことは世界の反対側か世界中の軌道にのっているコンピュータに含まれるにはもっともなことである。これはファイルシステム操作が思いもよらない手法で失敗するかもしれないことを暗示している。例えば、
(コードは、略)
最初の例は、ファイルは exists() を呼んでいる間に削除されてしまっているかもしれない。次の例は、ファイルは削除されてしまっていて is_directory() を呼んでいある間に同じディレクトリの名前によって置換されてしまう。
- Race-conditions may occur. Directory trees, directories, files, and file attributes are in effect shared between all threads, processes, and computers which have access to the
filesystem. That may well include computers on the other side of the
world or in orbit around the world. This implies that file system operations
may fail in unexpected ways. For example:
assert( exists("foo") == exists("foo") );
// may fail!
assert( is_directory("foo") == is_directory("foo");
// may fail!
In the first example, the file may have been deleted between calls to
exists(). In the second example, the file may have been deleted and then
replaced by a directory of the same name between the calls to is_directory().
-
たとえアプリケーションは移植性があるものになっても、それはまだ時々独自にパスシステムを通らなければならない。ユーザの入力した条件は共通の例である。
- Even though an application may be portable, it still will have to traffic
in system specific paths occasionally; user provided input is a common
example.
Requirements と Realities は、たくさんの C++ インターフェスデザイン上で進められた。特に、分かりやすいスクリプト系のコードが作る期待は大量のどうやら予期されていたような exists( "foo") のような単純な表現を確実にする効果を引き起こした。
The Requirements and
Realities above drove much of the C++ interface design. In particular,
the desire to make script-like code straightforward caused a great deal of
effort to go into ensuring that apparently simple expressions like exists( "foo"
) work as expected.
論理的基礎はたくさんデザインの議論の詳細の背景にあることを FAQ を参照せよ。
See the FAQ for the rationale behind many detailed
design decisions.
洞察力キーのいくつかは path クラス設計の内部に進んでいた。
- 入力フォーマットを切り離しているのは、内部的な概念モデル (vector<string> あるいは他のシーケンス) や出力フォーマットである。
- 2 つの入力フォーマットを提供していること (ノンブランドや独自の O/S) は主なデザインの行き詰まりを壊した。
- いくつかの出力フォーマットを提供していることは以前の扱いにくい問題をセットで解決した。
- いくつかの不透明な機能は (特に解凍や圧縮) 移植性のあるコードはサポートされていることを必要とした。(Peter Dimov, Thomas Witt, Glen Knowles, 他の方々)
Several key insights went into the path class design:
- Decoupling of the input formats, internal conceptual (vector<string>
or other sequence)
model, and output formats.
- Providing two input formats (generic and O/S specific) broke a major
design deadlock.
- Providing several output formats solved another set of previously
intractable problems.
- Several non-obvious functions (particularly decomposition and composition)
are required to support portable code. (Peter Dimov, Thomas Witt, Glen
Knowles, others.)
エラー検査していることは特に別領域になってしまう。一つのキーの洞察力はファイルやディレクトリの名前と移植性のある一般的な事実ではないことと共にあった。多少、プログラマーはどんなオペレーティングシステムに移植性があることを望んでいるのかという質問について考え抜かなければならない。この質問に対するいくつかの答えを提供しているものとして、Filesystem Library は最初の任務を要求する必要性をプログラマーたちに警告を出している。
Error checking was a particularly difficult area. One key insight was that
with file and directory names, portability isn't a universal truth.
Rather, the programmer must think out the question "What operating systems do I
want this path to be portable to?" By providing support for several
answers to that question, the Filesystem Library alerts programmers of the need
to ask it in the first place.
operations.hpp
Dietmar Khl 氏の独自の dir_it デザインと実装はファイルやディレクトリ名にワイド文字をサポートした。それは Library Working グループのメンバーの中にあった広範囲な議論はシステム上でワイド文字名は自然にサポートされていないという移植の意味論を識別する上で失敗した前に放棄された。FAQ を参照せよ。
Dietmar Khl's original dir_it design and implementation supported
wide-character file and directory names. It was abandoned after extensive
discussions among Library Working Group members failed to identify portable
semantics for wide-character names on systems not providing native support. See
FAQ.
インターフェース設計の相互作用の前にコンパイル時間あるいは実行時間がないオプションによって多数の便利な操作を提供している。それらは使うのにとても混乱してインターフェースとしてはるかに大きい機能名と同数存在していた。どんな利点も現実であるというのではなく理論的に見えた。
Previous iterations of the interface design used explicitly named functions providing a
large number of convenience operations, with no compile-time or run-time
options. There were so many function names that they were very confusing to use,
and the interface was much larger. Any benefits seemed theoretical rather than
real.
設計はコンパイル時間(実行時間でなく)フラグとオプション選択 (via ポリシー, enum あるいは int テンプレート引数) を元にすることはとてもちょっとした時間と努力を発明している後にしばしば放棄されたといった複雑ものになってきている。名前空間やエイリアスを用いた属性やオプション名の必要性は、現実的なコードを書いている現実を完全に評価できないテンプレート引数に不格好なものとして使われている。
すでに便利な機能セット(例えば 許容的な 削除, 簡潔にする 不法奪回, 他の操作, 加えて述べる, そして可能な他のもの, 未来に広々に広がる ) は詳細が複雑で議論を起こしたものになったという理由から放棄された。
Designs based on compile time (rather than runtime) flag and option selection
(via policy, enum, or int template parameters) became so complicated that they
were abandoned, often after investing quite a bit of time and effort. The need
to qualify attribute or option names with namespaces, even aliases, made use in
template parameters ugly; that wasn't fully appreciated until actually writing
real code.
Yet another set of convenience functions ( for example, remove with
permissive, prune, recurse, and other options, plus predicate, and possibly
other, filtering features) were abandoned because the details became both
complex and contentious.
どちらのユーザからの低いレベルで操作するツールキットは左にあるどんなものでも便利な操作より複雑に創造することができる。加えて、正当に含まれているものとして十分十分役に立つ少数の便利な機能が見つかっている。
What is left is a toolkit of low-level operations from which the user can
create more complex convenience operations, plus a very small number of
convenience functions which were found to be useful enough to justify inclusion.
path.hpp
たくさんの破棄されたパス設計があったが、私は進路を失ってしまった。いくつかの風味の中でポリシーを元にしたクラステンプレートは、コンストラクタはランタイムポリシーを供給しており、ランタイムポリシー独自の操作系、それらは全て考慮されているが、まれに実装されたものや小さな利益に気がつくとはあまりにも複雑になったものとして結局破棄されている。
There were so many abandoned path designs, I've lost track. Policy-based
class templates in several flavors, constructor supplied runtime policies,
operation specific runtime policies, they were all considered, often
implemented, and ultimately abandoned as far too complicated for any small
benefits observed.
error checking
エラー検査機能のためデザインの数は実装による試みの前に破棄されてしまった。完全自動エラー検査は特に試みられた。しかし、自動エラー検査はさらに複雑となった全般的なライブラリ設計を作る傾向になっていったのである。
A number of designs for the error checking machinery were abandoned, some
after experiments with implementations. Totally automatic error checking was
attempted in particular. But automatic error checking tended to make the overall
library design much more complicated.
いくつかのでデザインはパスを用いたエラー検査機構を結合させた。ポリシーを元にしたエラー検査テンプレート設計は部分的に実装され、日常のスクリプト系プログラムのためにますます複雑なものとなり破棄されていったのである。
Some designs associated error checking mechanisms with paths. Some with
operations functions. A policy-based error checking template design was
partially implemented, then abandoned as too complicated for everyday
script-like programs.
最終的なデザインはより単純でまっすぐなものとしてエラー検査機能呼び出しを独自の上で部分的に依存している。プログラマー訓練の上でのさまざまな拡張に依存している。しかし彼らのプログラムは選ばれたターゲットシステム上で正確に動作する合理的に確かなことした移植性について気にかけているプログラマーは好まれるべきである。
The final design, which depends partially on explicit error checking function
calls, is much simpler and straightforward, although it does depend to
some extent on programmer discipline. But it should allow programmers who
are concerned about portability to be reasonably sure that their programs will
work correctly on their choice of target systems.
[IBM-01] IBM Corporation, z/OS V1R3.0 C/C++ Run-Time
Library Reference, SA22-7821-02, 2001,
http://www-1.ibm.com/servers/eserver/zseries/zos/bkserv/
[ISO-9660] International Standards Organization, 1988.
[POSIX-01] Open Group, IEEE Std 1003.1-2001 [AKA
POSIX], 2001,
http://www.opengroup.org/onlinepubs/007904975/toc.htm
[Wulf-Shaw-73] William Wulf, Mary Shaw, Global
Variable Considered Harmful, ACM SIGPLAN Notices, 8, 2, 1973, pp. 23-34
© Copyright Beman Dawes, 2002
Revised
03 January, 2003