今回はFileReaderオブジェクトを使って、
FileReaderオブジェクトを使ったファイルロード
PERSISTENTファイルシステムのファイル一覧を表示し、
新たに登場するオブジェクトとメソッドは次のとおりです。
- FileReaderオブジェクト
- readAsDataURLメソッド
- readAsTextメソッド
これまでと同様、
PERSISTENTファイルシステムのファイル一覧を表示。ファイル名をクリックして、ファイル内のデータを表示(iOS/Android)
PERSISTENTファイルシステムのファイル一覧を表示し、
テスト用のソースコードは次のとおりです。
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5 <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" />
6 <title>File API Test (5)</title>
7 </head>
8 <body>
9 <div class="app">
10 <h1>File API Test</h1>
11 <ul id="fileList"></ul>
12 <div id="viewer" style="display: none">
13 <table>
14 <tr>
15 <th>ファイル名</th>
16 <td id="fileName"></td>
17 </tr>
18 <tr>
19 <th>ファイルサイズ</th>
20 <td id="fileSize"></td>
21 </tr>
22 </table>
23 <div id="fileContents"></div>
24 <input id="back" type="button" value="Back">
25 </div>
26 </div>
27 <script type="text/javascript" src="cordova-2.0.0.js"></script>
28 <script type="text/javascript">
29 var directoryEntry;
30
31 document.addEventListener('deviceready', init, false);
32 function init() {
33 // PERSISTENTファイルシステムを取得
34 window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, getFilesFromDirectory, fail);
35 document.getElementById('back').addEventListener('click', back, false);
36 }
37
38 function getFilesFromDirectory(fileSystem) {
39 // FileSystemオブジェクトのrootプロパティには、DirectoryEntryオブジェクトが格納されている
40 directoryEntry = fileSystem.root;
41
42 // DirecotryEntryオブジェクトのcreateReaderメソッドを使い、
43 // ディレクトリ内のファイルを読み込むためのDirectoryReaderオブジェクトを生成
44 var directoryReader = directoryEntry.createReader();
45
46 // DirectoryReaderオブジェクトのreadEntriesメソッドを使い、
47 // ディレクトリ内のエントリを読み込み、コールバック関数に配列として渡す
48 directoryReader.readEntries(putFileName, fail);
49 }
50
51 function putFileName(entries) {
52 // ディレクトリ内のエントリがFileEntryオブジェクトまたは
53 // DirectoryEntryオブジェクトとして配列で渡される
54 for ( index = 0; index < entries.length; index++ ) {
55 // ファイルのみを表示する (ディレクトリは表示しない)
56 if ( entries[index].isFile ) {
57 // ファイル名を格納する DOM を生成
58 var listItem = document.createElement('li');
59 listItem.textContent = entries[index].name;
60 listItem.title = entries[index].fullPath;
61 listItem.addEventListener('click', viewFileEntry, false);
62
63 // 作成した DOM を <ul id="fileList"></ul> に挿入
64 document.getElementById('fileList').appendChild(listItem);
65 }
66 }
67 }
68
69 function viewFileEntry(event) {
70 // FileEntryオブジェクトを取得
71 directoryEntry.getFile(event.target.textContent, null, getFile, fail);
72 }
73
74 function getFile(fileEntry) {
75 // Fileオブジェクトを取得
76 fileEntry.file(readFile, fail);
77 }
78
79 function readFile(file) {
80 var reader = new FileReader();
81 document.getElementById('fileName').textContent = file.name;
82 document.getElementById('fileSize').textContent = file.size;
83
84 // ファイルタイプの判定
85 // Androidの場合は、Fileオブジェクトのtypeプロパティから判定
86 // iOSの場合は、Fileオブジェクトのnameプロパティから、拡張子で判定
87 if
88 (
89 ( 'Android' === device.platform && 'jpg' === file.type ) ||
90 ( file.name.match(/\.jpg$/i) )
91 ) {
92 // 画像ファイルを readAsDataURL で読み込み
93 reader.readAsDataURL(file);
94 reader.onloadend = function(event) {
95 document.getElementById('fileList').style.display = 'none';
96 document.getElementById('viewer').style.display = 'block';
97 var img = new Image();
98 img.src = event.target.result;
99 img.onload = function() {
100 document.getElementById('fileContents').appendChild(img);
101 }
102 }
103 }
104 else if
105 (
106 ( 'Android' === device.platform && 'txt' === file.type ) ||
107 ( file.name.match(/\.txt$/i) )
108 ) {
109 // テキストファイルを readAsText で読み込み
110 reader.readAsText(file);
111 reader.onloadend = function(event) {
112 document.getElementById('fileContents').textContent = event.target.result;
113 document.getElementById('fileList').style.display = 'none';
114 document.getElementById('viewer').style.display = 'block';
115 document.getElementById('fileContents').style.whiteSpace = 'pre';
116 }
117 }
118 }
119
120 function back() {
121 document.getElementById('fileName').textContent = '';
122 document.getElementById('fileSize').textContent = '';
123 document.getElementById('fileContents').textContent = '';
124 document.getElementById('fileList').style.display = 'block';
125 document.getElementById('viewer').style.display = 'none';
126 document.getElementById('fileContents').style.whiteSpace = 'normal';
127 }
128
129 function fail(error) {
130 // エラーについては http://docs.phonegap.com/en/2.0.0/cordova_file_file.md.html#FileError を参照
131 alert('エラーが発生しました。エラーコード: ' + error.code);
132 }
133 </script>
134 </body>
135 </html>
まずはiOSで実行してみましょう。アプリケーションを起動すると、

ファイル名をクリックすると、


iOSシミュレータでファイルを取り扱うアプリケーションを作成する場合、
具体的な手順は次のとおりです。
- Xcodeの対象プロジェクトを選択している状態で、
上部メニューの [Product] より [Edit Scheme] をクリック - Build Condigurationのプルダウンを選択し、
[Debug] から [Release] に変更 - 右下の
[OK] ボタンをクリック
![Xcodeの対象プロジェクトを選択している状態で、上部メニューの[Product]より[Edit Scheme]をクリック Xcodeの対象プロジェクトを選択している状態で、上部メニューの[Product]より[Edit Scheme]をクリック](/assets/images/dev/serial/01/phonegap2/0007/thumb/TH800_004.jpg)

![[Debug]から[Release]に [Debug]から[Release]に](/assets/images/dev/serial/01/phonegap2/0007/006.jpg)
Build Configurationを変更することで、
続いて、



このサンプルコードでは、
- requestFileSystemでPERSISTENTファイルシステムを取得
- FileSystemオブジェクトのrootプロパティから、
PERSISTENTファイルシステムのルートディレクトリの情報 (DirectoryEntryオブジェクト) を取得 - DirectoryEntryオブジェクトのcreateReaderメソッドを用いて、
DirectoryReaderオブジェクトを作成 - DirectoryReaderオブジェクトのreadEntriesメソッドを用いて、
ディレクトリ内のファイル/ディレクトリエントリを読み込む - readEntriesメソッドから渡されたFileEntry/
DirectoryEntryの配列を受け取り、 ファイルのみを<li>要素で列挙。ファイル名をクリックすることでFileEntryオブジェクトを取得するように - FileEntryオブジェクトからFileオブジェクトを取得
- FileReaderオブジェクトを作成。Fileオブジェクトと組み合わせて、
ファイルデータを読み込み、 ファイル情報と一緒に画面に表示する
PERSISTENTファイルシステム内のファイルを列挙するところまでは、
55 // ファイルのみを表示する (ディレクトリは表示しない)
56 if ( entries[index].isFile ) {
57 // ファイル名を格納する DOM を生成
58 var listItem = document.createElement('li');
59 listItem.textContent = entries[index].name;
60 listItem.title = entries[index].fullPath;
61 listItem.addEventListener('click', viewFileEntry, false);
62
63 // 作成した DOM を <ul id="fileList"></ul> に挿入
64 document.getElementById('fileList').appendChild(listItem);
65 }
viewFileEntry関数は、
69 function viewFileEntry(event) {
70 // FileEntryオブジェクトを取得
71 directoryEntry.getFile(event.target.textContent, null, getFile, fail);
72 }
71行目のgetFileメソッドの第3引数に指定しているgetFile関数では、
74 function getFile(fileEntry) {
75 // Fileオブジェクトを取得
76 fileEntry.file(readFile, fail);
77 }


76行目のfileメソッドの第1引数に指定しているreadFile関数は、
79 function readFile(file) {
80 var reader = new FileReader();
81 document.getElementById('fileName').textContent = file.name;
82 document.getElementById('fileSize').textContent = file.size;
FileReaderオブジェクトのプロパティは次のとおりです。
- readyState:
- EMPTY
(0: 何も読み込んでいない) , LOADING (1: 読み込み中) , DONE (2: 読み込み完了) のうち、 いずれかの状態を示します - result:
- readAsDataURLメソッド, readAsTextメソッドで読み込んだファイルのデータを格納します
- error:
- エラー発生時にFileErrorオブジェクトを格納します
- onloadstart:
- イベントハンドラ。ファイルのロード開始時に呼び出したい関数を指定します
- onprogress:
- イベントハンドラ。ファイルのロード中に呼び出したい関数を指定します。現在サポートされていない機能です
- onload:
- イベントハンドラ。ファイルのロード完了時に呼び出したい関数を指定します
- onabort:
- イベントハンドラ。ファイルのロード中止時に呼び出したい関数を指定します
- onerror:
- イベントハンドラ。ファイルロード失敗時に呼び出したい関数を指定します
- onloadend:
- イベントハンドラ。ファイルロードの成功/失敗問わずにリクエストが完了した際に呼び出したい関数を指定します
FileReaderオブジェクトに用意されているメソッドは次のとおりです
メソッド名 | 内容 |
---|---|
使い方 | |
abort | ファイルの読み込みを中止します。 |
fileReader. |
|
readAsDataURL | ファイルを読み込み、
|
fileReader. |
|
readAsText | ファイルを読み込み、
|
fileWriter. |
コードの解説に戻ります。ここでは続けてファイルタイプの判定を行っています。Androidの場合はFileオブジェクトのtypeプロパティから、
84 // ファイルタイプの判定
85 // Androidの場合は、Fileオブジェクトのtypeプロパティから判定
86 // iOSの場合は、Fileオブジェクトのnameプロパティから、拡張子で判定
87 if
88 (
89 ( 'Android' === device.platform && 'jpg' === file.type ) ||
90 ( file.name.match(/\.jpg$/i) )
91 ) {
104 else if
105 (
106 ( 'Android' === device.platform && 'txt' === file.type ) ||
107 ( file.name.match(/\.txt$/i) )
108 ) {
ファイルが画像
92 // 画像ファイルを readAsDataURL で読み込み
93 reader.readAsDataURL(file);
FileReaderオブジェクトに用意されているonloadendイベントをもちいて、
94 reader.onloadend = function(event) {
95 document.getElementById('fileList').style.display = 'none';
96 document.getElementById('viewer').style.display = 'block';
97 var img = new Image();
98 img.src = event.target.result;
99 img.onload = function() {
100 document.getElementById('fileContents').appendChild(img);
101 }
102 }
ファイルがテキスト
109 // テキストファイルを readAsText で読み込み
110 reader.readAsText(file);
FileReaderオブジェクトに用意されているonloadendイベントをもちいて、
111 reader.onloadend = function(event) {
112 document.getElementById('fileContents').textContent = event.target.result;
113 document.getElementById('fileList').style.display = 'none';
114 document.getElementById('viewer').style.display = 'block';
115 document.getElementById('fileContents').style.whiteSpace = 'pre';
116 }
back関数はファイル情報詳細画面から一覧画面に戻るための関数です。ファイル情報が格納されている要素を初期化し、
120 function back() {
121 document.getElementById('fileName').textContent = '';
122 document.getElementById('fileSize').textContent = '';
123 document.getElementById('fileContents').textContent = '';
124 document.getElementById('fileList').style.display = 'block';
125 document.getElementById('viewer').style.display = 'none';
126 document.getElementById('fileContents').style.whiteSpace = 'normal';
127 }
昨今ではJavaScriptでバイナリを操作するオープンソースのライブラリもいくつか登場してきています。速度の面を突き詰めると各デバイス向けのネイティブアプリケーションを実装するのがベストですが、
次回はファイル転送に関係するオブジェクトの紹介と、