ストレージとメインメモリの違い

ITmediaにこんな記事が掲載されていた。

知らないと恥ずかしい? メモリの「RAM」と「ROM」の違い - ITmedia NEWS

PCにある程度詳しい人でなければ、メインメモリ(RAM)とストレージ(HDDやSSD等)の違いというのはなかなか分かり難いようで、実際僕の周りでもこの区別がついてない人は多く、説明に苦労した経験がある。
これらは少し昔の、HDD主流の時代から混同されやすかったが、SSD(フラッシュメモリ)の登場以来、その違いはなおさら解りにくくなっている。なぜならばフラッシュメモリもメモリの一種だからだ。

上記ITmediaでは混同の問題が、RAMとROMの違いという視点から書かれている。 けれどこの混同の根本的な原因はそこではなく、「メインメモリ(主記憶装置)」と「ストレージ(補助記憶装置)」の違いと、それらの働きが理解できていない事によるものだろう。

2017年現在、PCやスマホなどのメインメモリはRAM(DRAM)だ。しかしながら、メインメモリがRAMである必然性はない。 メインメモリには今現在、RAMが最も適しているからRAMを採用しているに過ぎない。 高速にデータを読み書きできるのであれば何もRAMである必要はなく、それどころか半導体メモリである必要すらない。その意味では「主記憶装置」という表現がより適切だが、ここでは一般的な表現を軸に説明する。

メインメモリがRAMである理由

PCやスマホを含む現在のあらゆるコンピュータは基本的に、何らかのデータ(とプログラム)を元に内部で複雑な処理(演算)を行い、その結果を画面に表示したり、外部に転送したり、内部に蓄積しておいたりする。 その処理をする過程で、一時的に、極めて高速にデータを読み書きできる保管場所が必要になる。それが「主記憶装置(メインメモリ)」だ。

主記憶装置は、高速に読み書きできる事が最も重要な為、高速かつ実用的な価格で製造できるDRAMがほとんどのコンピュータに採用されている。 DRAMはその構造上、電源供給が途絶えればあっという間にデータが消えてしまうという重大な弱点があるものの、この用途だと処理が完了すればデータが消えてしまっても構わないから問題にはならない。だがそれ故に、データを恒久的に蓄えておく場所「補助記憶装置(ストレージ)」が必要になる。

ストレージの現在と混同

ストレージは、電源を切っても消えないという特長の他に、安価かつ大容量である事が求められる。 その期待に応えられるのが、HDDだった。最近ではSSDなどのフラッシュメモリも、比較的小さな容量ではHDDに迫るか、むしろHDDより安価に製造できるようになってきている。 加えて小型で軽量、衝撃にも強いフラッシュメモリは、スマホを始めとする携帯端末において圧倒的なシェアを占めている。

RAMとROMの違いについてはITmediaの記事を参考にして頂くとして、そのような訳で、現在のコンピュータにはメインメモリとストレージという用途の違う記憶装置が必要であり、それらにDRAM及びHDD、フラッシュメモリが採用されてきたわけだ。

何を記憶装置に採用するかは、技術進歩と必要に応じて変化してゆくものだ。だから一般に混同されているものは、RAMとフラッシュメモリやROMの違いというよりも、メインメモリとストレージの違いだと言える。

ストレージがROMと呼ばれる理由

ITmediaの記事にも書かれている通り、ストレージをROMと表現するのは極めて不自然だ。 なぜならばストレージは読み書き(と消去)できるものであるにも関わらず、ROMという用語は読み取り専用のメモリを意味しているからだ。

件の記事では下の通り、スマホ等においてROMと表現される理由を「なぜか」と言っているが、フラッシュメモリの歴史的経緯を知れば原因らしいものが見えてくる。

国内で携帯電話などのサービスを提供する通信キャリアが公開しているスマートフォンのスペック表を見ると、なぜかデータを保存するストレージ容量を「ROM ○GB」として表記する慣習がある。2017年現在も大手3キャリアのスペック表を見ると、保存領域の容量をROMとして表現している。まるでRAMの対義語かのように。

現在でこそフラッシュメモリは頻繁に書き換えるストレージなどの用途に使われている。だが、当初のフラッシュメモリは高価・小容量などの理由で、ファームウェア(電子機器を制御する為の基盤プログラム)などのごく限られた用途にのみに使われていた。
そういった用途では、不具合修正等のアップデートや設定変更以外では書き換える必要がないため、特別な手順を踏まなければ書き換えられず、通常時は読み出し専用として使われていた。そしてそういう用途のフラッシュメモリは「フラッシュROM」とも呼ばれていた。

もうお解りだと思うが、このフラッシュROMという用語が、略して「ROM」と表記されるようになり、本来の意味が失われて今に至ってしまったというのが事の顛末ではないかと思われる。

蛇足ながら個人的には、RAMの対義語はROMで大体合ってると思う(消去書き込みの可否という意味で)。

メインメモリとストレージの未来

メインメモリとストレージは近い将来、統合という新たな段階を迎えようとしている。 DRAMの「電源を切ると消えてしまう」という欠点を解消し、高速動作を維持しつつ電源が無くても消えない新しいメモリの開発が進んでいるからだ。 この新メモリをメインメモリに採用すれば、原理的には現在のストレージは不要になる。PCやスマホに搭載するのは1種類の新メモリだけで良いので、同時に混同問題も解消する。いつでも瞬時に電源のオン・オフが出来るので、省電力にも大きく貢献するだろう。

課題は信頼性と価格、生産効率だが、もしHDDやSSDに迫る信頼性と価格で大量生産が可能になれば、あっという間にDRAMもHDDもフラッシュメモリも過去の遺物になってしまう可能性がある。現在の見込みではフラッシュメモリ価格の5倍程度と高価だそうだが、そんな夢のような未来が訪れるのだろうか?
しかし今まで夢を何度も実現してきたコンピュータの世界だ。夢の未来は案外すぐに到来する。

参考

テーマ: パソコン - ジャンル: コンピュータ

「Dropboxに移動」を右クリックメニューから削除する

WindowsにDropboxをインストールすると、エクスプローラーの右クリックメニュー(コンテキストメニュー)へ「Dropbox」に移動 が追加されます。 しかしDropboxの設定には、この項目をメニューから削除する設定がありません。 その為、レジストリを編集する事になりますが比較的簡単に非表示化できますので、その方法をご紹介します。

対象OS

Windows 10 及び Windows 8, 7, Vista

変更の前に

レジストリの変更方法が解る方向けに書いています。レジストリに間違った変更を加えると Windowsの動作に支障をきたす可能性もありますので、変更作業の際はくれぐれもご注意ください。

設定方法

下記の手順に従って設定します。

  1. regedit(レジストリエディタ)を起動します。
  2. HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions」を開きます。
  3. 「右クリック>新規>キー」で新しいキー「Blocked」を作ります。
  4. Blockedを開き、「右クリック>新規>文字列値」で名前に「{ECD97DE5-3C8F-4ACB-AEEE-CCAB78F7711C}」と入力します。
  5. レジストリエディタを閉じて、Windowsを再起動します。(再サインインかエクスプローラの再起動でもOK)

レジストリエディタでShell Extensions\Blockedを開いた所

設定後は「Dropbox」に移動 が表示されなくなります。

表示状態に戻すには

この設定は特定のメニュー項目を非表示にしているだけなので、上記で追加した文字列値をBlockedから削除すれば設定前の表示状態に戻すことも可能です。

関連情報ページ

テーマ: Windows10 - ジャンル: コンピュータ

CSSで画像やブロックの幅を可変にする max-widthとmin-width

max-widthmin-widthは、CSS2.1から使えるようになった要素の最大/最小幅を指定するプロパティです。 CSS3の実装が進んだ現在は、PCとスマートフォンのほぼ全てのブラウザで利用可能です。

この記事では、レスポンシブデザインに欠かせない、widthを含めた3つのプロパティの関係と、可変幅の指定方法について解説します。

max-widthとmin-width

要素(画像やブロック)に対してmax-widthで表示する最大幅を、min-widthで最小幅を指定できます。 これらのプロパティを応用することで、ブラウザの幅に連動した要素幅の可変が実現できます。

なおページ全体の幅が固定であれば、通常通りwidthのみで幅を決定したほうが描画速度的に有利です。

幅指定の優先度

要素の幅を指定するCSSプロパティは、下記のように min-widthが最も優先されます。

min-width > max-width > width

これらを指定すると、実際に表示される幅(width)はmin-widthmax-widthの間の値に制限されます。
また、3つのうちでmin-widthに最も大きな幅を指定すると、max-widthwidthにどんな値を指定しても min-widthの幅で固定になります。

widthの100%とauto

widthの100%は、親ブロックの幅に対しての100%です。 その為、画像に100%を指定すると、画像本来の幅は無視されます。

画像にwidth: autoを指定すると、ブラウザにより画像本来の幅が設定されます。

画像幅を可変にする

レスポンシブデザインでは、画像の幅をブラウザ幅の変動に合わせて可変にしたい場合があります。 CSS2.1以降はそれを可能にする方法がいくつか有りますが、ブラウザ毎の実装状況の差も有り、現時点での選択肢は限られています。

概ね下記の何れかのような指定になるでしょう。

.A {
    width: 100%;
    max-width: 500px;
    min-width: 300px;
    height: auto;
}

.B {
    width: 500px;
    max-width: 100%;
    min-width: 300px;
    height: auto;
}

.C {
    width: auto;
    max-width: 100%;
    min-width: 300px;
    height: auto;
}

Awidth: 100%で画像の幅が親要素の幅に連動するようになります。 最大幅はmax-width、最小幅はmin-widthによって制限されますので、それぞれの値に達するとそれ以上変動せず、親要素の幅は無視されます。 論理的には最も明確と言えます。

Bでは、max-widthは100%ですが、最大でもwidthの幅を超えることは無く、widthより狭い時はmin-widthの幅になるまで連動します。結果的に、Aと同様の動作になります。

CもBと近い動作で、width: autoにより画像本来の幅が最大幅になる点だけが違います。 CSS側で最大幅を制限できない為、レスポンシブデザインとの相性はあまり良くありません。

BとCの場合、MDNの解説に拠れば max-widthwidthよりも優先するはずで、最大幅は親ブロックの内側の幅になりそうですが、親ブロックが充分に大きい場合でも実際にはそうなりません (Chrome, Firefox, Edgeの何れも)。
以上から、max-widthが100%の場合、最大幅はwidthの幅になると考えて良さそうです。

min-widthは何れも任意の最小幅を指定します。ここでは300pxとしています。

heightautoと指定してブラウザによる自動計算に任せます。これで、幅が変わった時でも画像本来の縦横比を維持したまま最適な高さになります。

確認環境

2017年3月時点のFirefox及びChrome最新版(Windows)で動作確認しました。
また、Chromeによるスマートフォンのエミュレーションでもテストしました。

参考URL

テーマ: HTML&スタイルシート(CSS) - ジャンル: コンピュータ

PHPで文の中間を省略して一定の幅に収める

「文の中間を省略して一定の幅に収める」処理は需要がありそうですが、検索してみた限りでは見つからなかったので作ってみました。

PHPには、文字列が一定の長さ(幅)を超えたら丸める関数 mb_strimwidth()が標準で有ります。しかし、この関数だけでは文字列の中間を省略する事はできませんので、この関数を応用して、一定の幅を超えたら指定位置の文字列を省略する関数にしました。少し長いですが、ソースコードは下記の通りです。

<?php
// 文字列の途中を省略して最大幅以内にする
// string $str        = 対象文字列
// int    $maxWidth   = 最大幅 (mb_strwidth準拠)
// int    $cutPos     = 省略位置。正の値は先頭から(0が先頭)、負の値は末尾からの幅。Falseで中央。
// string $trimMarker = 省略記号にする文字列
// @return string
function sMidTrim ($str, $maxWidth, $cutPos = False, $trimMarker = '..') {

    // 文字列の幅を取得
    $strWidth = mb_strwidth($str);
    if($strWidth <= $maxWidth) { return $str; }

    // マーカーの幅を取得
    $tmWidth = mb_strwidth($trimMarker);
    if($tmWidth + 2 > $maxWidth) { return $str; }

    // カットすべき幅を算出
    $cutoffWidth = $tmWidth + $strWidth - $maxWidth;

    // カットの始点(幅)を算出
    $remain = $strWidth - $cutoffWidth;
    if(!is_int($cutPos)) {
        // 無指定時は中央
        $cutBeginWidth = ceil( $remain / 2 );
    }
    elseif($cutPos >= 0) {
        // 正の値
        if($cutPos > $remain) { $cutPos = $remain; }
        $cutBeginWidth = $cutPos;
    }
    else {
        // 負の値
        $cutBeginWidth = $remain + $cutPos;
        if(0 > $cutBeginWidth) { $cutBeginWidth = 0; }
    }

    // 先頭文字列を切り出す
    $headStr = mb_strimwidth($str, 0, $cutBeginWidth);

    // 末尾文字列を切り出す
    $pos = mb_strlen( mb_strimwidth($str, 0, $cutBeginWidth + $cutoffWidth) );
    $tailStr = mb_substr($str, $pos);

    return $headStr.$trimMarker.$tailStr;
}

解説

出来る限りソースコードのみで解るように書いたつもりですが、いくつか補足します。

引数のうち、第2及び第3引数は「幅」単位で指定するようになっています。 これはmb_strimwidth()で使われる幅と同じものです。

第3引数で指定された位置に省略記号(第4引数で指定可)が挿入されます。 なお、末尾に省略記号を付ける動作はmb_strimwidth()で可能ですので省きました。

第1引数で渡された文字列が第2引数の幅に満たない場合は、何も処理を行わず文字列をそのまま返します。 省略記号が付加されるのは、省略しないと指定された幅に収まらない場合のみです。

関連記事 PHPのmb_strimwidthが意図通り動かない問題

利用時の注意

PHP5.6で動作確認しました。PHP5以降であれば恐らく動くと思います。

マルチバイト文字列関数(mb_*)を呼び出していますので、実際の挙動はそれらの関数に依存します。 予めmb_internal_encoding()で適切な内部文字エンコーディングを設定してからご利用ください。

コードは非商用に限り、そのままご利用頂いても構いません。
適切に動作するよう心がけましたが、不具合があるかもしれません。無保証ですのでその点はご了承願います。利用やバグ等の報告は頂ければ嬉しいです。

テーマ: プログラミング - ジャンル: コンピュータ

PHPのmb_strimwidthが意図通り動かない問題

PHPのmb_strimwidth()は文字列を指定した幅に丸めることが出来る便利な関数ですが、この関数に固有の特殊な点がいくつかあり、意図通りに動作しないことも多いかと思います。それらの点について解説します。

mb_strimwidthの引数
string mb_strimwidth ( string $str , int $start , int $width [, string $trimmarker = "" [, string $encoding = mb_internal_encoding() ]] )

mb_strimwidthの「幅」とは

PHPのマルチバイト文字列関数(mb_*)の多くは文字列をバイトではなく文字単位で扱い、まさにそれがこの関数群を利用するメリットなわけですが、mb_strimwidth()mb_strwidth()は文字列の「幅」を扱うようになっています。

これらの関数が扱う「幅」とは、文字数やピクセル数のことではありません。1バイト文字の幅を1、全角文字を含むマルチバイト文字の幅を2として計算した、画面に表示される際のおおよその推定幅を意味します。
実際の表示においては文字列のピクセル幅はフォント等に依存しますので、きっちり同じ幅にはなりませんが、ある程度揃えば良い場合には便利な単位です。

第2引数 $startの注意点

$startで指定するのは、丸めの開始位置ではなく切り出し始めの位置です。従って、文字列の先頭を切る必要がなく、末尾だけを丸めたい場合は 0と指定します。

また、単位が「幅」ではなく「文字数」である点にも注意が必要です。続く第3引数は幅で指定しますから余計に解りにくくなっています。 $startを幅で指定したい場合は一旦mb_strimwidth()で任意の幅を切出し、その文字数をmb_strlen()でカウントしてからもう一度mb_strimwidth()を使う必要があります(ちょっと困りものですね)。

<?php
// 3文字目から幅6相当の文字列を取得
$s = mb_strimwidth('さんぷるabcde', 2, 6);

// $s = 'ぷるab'

第4引数 $trimmarkerの注意点

$trimmarkerの幅は第3引数$widthに含まれます。

<?php
$s = mb_strimwidth('さんぷるabcde', 2, 6, '..');

// $s = 'ぷる..'

$widthの幅に$trimmarkerを含みたくない場合は、下記のようにします。

<?php
$s = mb_strimwidth('さんぷるabcde', 2, 6).'..';

// $s = 'ぷるab..'

内部文字エンコーディングの指定を忘れずに

マルチバイト文字列関数による文字数及び幅の処理は、内部文字エンコーディングに依存しています。内部文字エンコーディングと扱う文字列の文字コードが一致しない場合は正常に動作しませんので、必ず指定しましょう。また、ソースコード自体の文字コードの不一致も文字化けの原因になりますので注意しましょう。

予めmb_internal_encoding()で一度指定しておけば、以降内部文字エンコーディングに依存する関数は全てこれに従います。また、関数の引数でその都度文字コードを指定することもできます。

<?php
// UTF-8の場合
mb_internal_encoding('UTF-8');

// SJIS(Windows)の場合
mb_internal_encoding('CP932');

CSSを使う方法もある

ウェブブラウザ上で特定サイズ内に文字列を収めたい場合は、mb_strimwidth()ではなくCSSを使う方法もあります。

CSSでは、text-overflow: ellipsisoverflow: hiddenを併用することで、指定されたボックス内に収まらないテキストは自動的に省略されます。こちらのほうがPHPで処理するよりも綺麗に収まりますが、複数行に対応させようとすると記述が複雑になる等の難点もあります。これらのプロパティの詳細は下記URLをご参照ください。

テーマ: プログラミング - ジャンル: コンピュータ