ファイルシステム使用

2020-12-16 hit count image

リアクトネイティブ(React Native)プロジェクトでreact-native-fsライブラリを使ってファイルを読んだり書いたりしてみましょう。

概要

リアクトネイティブ(React Native)で開発する時、しばしばファイルシステム(filesystem)を使ってファイルを読んだり書いたりする場合が発生します。react-native-fsはリアクトネイティブ(React Native)でファイルシステム(filesystem)をもっと簡単に使えるように助けてくれるライブラリです。このブログではreact-native-fsを使う方法について説明します。

インストール

リアクトネイティブ(React Native)でファイルシステム(filesystem)を使うために下記のコマンドを使ってreact-native-fsをインストールします。

npm install --save react-native-fs

インストールが完了されたら、下記のコマンドでreact-native-fsとリアクトネイティブ(React Native)プロジェクトを連結します。

react-native link react-native-fs

使い方

ファイルシステム(filesystem)を使ってファイルを読んだり書いたりする色んな方法について公式サイトに詳しく載せております。ここには簡単にファイルを読んだり書いたりする部分について説明します。

ディレクトリ

下はreact-native-fsが定義してるファイルシステムのディレクトリ/パス(filesystem directory/path)です。

  • MainBundlePath: メインバンドルフォルダ(Main Bundle Directory)の絶対位置です(アンドロイドでは使えません。)
  • CachesDirectoryPath: キャッシュフォルダ(Cache Directory)の絶対位置です。
  • ExternalCachesDirectoryPath: 外部キャッシュフォルダ(External Cache Directory)の絶対位置です。(iOSでは使えません。)
  • DocumentDirectoryPath: ドキュメントフォルダ(Document Directory)の絶対位置です。
  • TemporaryDirectoryPath: 臨時フォルダ(Temporary Directory)の絶対位置です。(アンドロイドではキャッシュフォルダと同じです。)
  • LibraryDirectoryPath: iOSのNSLibraryDirectoryの絶対位置です(アンドロイドでは使えません。)
  • ExternalDirectoryPath: 外部ファイル共有フォルダ(External files, shared directory)の絶対位置です。(iOSでは使えません。)
  • ExternalStorageDirectoryPath: 外部ストレじ共有フォルダ(External storage, shared directory)の絶対位置です。(iOSでは使えません。)

フォルダ読み

下はリアクトネイティブ(React Native)でreact-native-fsを使ってフォルダを読む方法に関するコードです。

...
// typescript style
import * as RNFS from 'react-native-fs';
...

//readDir(dirpath: string)
RNFS.readDir(RNFS.DocumentDirectoryPath).then(files => {
    ...
})
.catch(err => {
    ...
    console.log(err.message, err.code);
    ...
});
...

ファイル読み

下はリアクトネイティブ(React Native)でreact-native-fsを使ってファイルを読む方法に関するコードです。

...
// typescript style
import * as RNFS from 'react-native-fs';
...

// readFile(filepath: string, encoding?: string)
RNFS.readFile(filePath, 'ascii').then(res => {
    ...
})
.catch(err => {
    ...
    console.log(err.message, err.code);
    ...
});
...

ファイル書き

下はリアクトネイティブ(React Native)でreact-native-fsを使ってファイルを書く方法に関するコードです。

...
// typescript style
import * as RNFS from 'react-native-fs';
...

// writeFile(filepath: string, contents: string, encoding?: string)
RNFS.writeFile(savePath, contents, 'ascii').then(res => {
    ...
})
.catch(err => {
    ...
    console.log(err.message, err.code);
    ...
});
...

ファイル削除

下はリアクトネイティブ(React Native)でreact-native-fsを使ってファイルを削除する方法に関するコードです。

...
// typescript style
import * as RNFS from 'react-native-fs';
...

// unlink(filepath: string)
RNFS.unlink(`${RNFS.DocumentDirectoryPath}/temp/`).then(res => {
    ...
})
.catch(err => {
    ...
    console.log(err.message, err.code);
    ...
});
...

イメージの使い方

写真を取ったり、カメラロールから写真を持ってくるためreact-native-image-pickerライブラリを使います。詳しい内容は下記のブログポストを確認してください。

react-native-image-pickerライブラリを使って持ってきたイメージをreact-native-fsを使ってコピーします。


import ImagePicker from 'react-native-image-picker';
...
ImagePicker.showImagePicker(options, (response) => {
    console.log('Response = ', response);

    if (response.didCancel) {
        console.log('User cancelled image picker');
    } else if (response.error) {
        console.log('ImagePicker Error: ', response.error);
    } else if (response.customButton) {
        console.log('User tapped custom button: ', response.customButton);
        Alert.alert(response.customButton);
    } else {
        // You can also display the image using data:
        // const source = { uri: 'data:image/jpeg;base64,' + response.data };
        const imagePath = `${RNFS.DocumentDirectoryPath}/${new Date().toISOString()}.jpg`.replace(/:/g, '-');

        if(Platform.OS === 'ios') {
            RNFS.copyAssetsFileIOS(response.origURL, imagePath, 0, 0)
                .then(res => {})
                .catch(err => {
                    console.log('ERROR: image file write failed!!!');
                    console.log(err.message, err.code);
                });
        } else if(Platform.OS === 'android') {
            RNFS.copyFile(response.uri, imagePath)
                .then(res => {})
                .catch(err => {
                    console.log('ERROR: image file write failed!!!');
                    console.log(err.message, err.code);
                });
        }
    }
});

そして下記のようにイメージを使えます。


<Image
    style={{width: 250, height: 250,}}
    source={{
        uri: Platform.OS === 'ios' ?
            imagePath
            : `file://${imagePath}`,
    }}
/>

ウェブビューでもコピーしたイメージを直接使えることができます。


import { WebView } from 'react-native-webview';

const imagePath = `${RNFS.DocumentDirectoryPath}/${new Date().toISOString()}.jpg`.replace(/:/g, '-');
const html = `<img src="${imagePath}" style="position: relative; max-width: 100%; max-height: 100%;"/>`;

<WebView
    originWhitelist={['*']}
    allowUniversalAccessFromFileURLs={true}
    allowFileAccessFromFileURLs={true}
    allowFileAccess={true}
    source={{
        html,
        baseUrl: 'file://',
    }}
/>

現在iOSのデバイスでイメージが表示されないバグがあります。(方法が間違ったかま。。表示できる方は教えてください。)

他の機能

react-native-fsで使える機能を共通/iOS/アンドロイド別で整理してみました。 詳しく内容は公式サイトを参考してください。

共通

下記のリストはreact-native-fsでOSと関係なく使える共通な機能です。

  • readDir(dirpath: string): パラメータでもらって絶対位置(Absolute path)のフォルダを読む
  • readdir(dirpath: string): NodejsスタイルのreadDir
  • stat(filepath: string): パラメータのファイル位置のファイルのステータスを取得
  • readFile(filepath: string, encoding?: string): パラメータのファイル位置のファイルを読む。encodingはutf8(default), ascii, base64を提供するし、base64はバイナリファイルを読む時使う。
  • read(filepath: string, length = 0, position = 0, encodingOrOptions?: any): パラメータのファイル位置のファイルに特定位置(position)へ長さが(length)ほどファイルの内容を読む。encodingはreadFileと同じです。
  • writeFile(filepath: string, contents: string, encoding?: string): 指定したファイル位置にファイルを記録する。
  • appendFile(filepath: string, contents: string, encoding?: string): 指定したファイルにファイルの内容を追加する。
  • write(filepath: string, contents: string, position?: number, encoding?: string): ファイルの特定位置(position)へファイル内容を追加する。
  • moveFile(filepath: string, destPath: string): ファイルを移動する。
  • copyFile(filepath: string, destPath: string): ファイルをコピする。
  • unlink(filepath: string): ファイルを削除する。
  • exists(filepath: string): ファイルが存在するかどうかファイルが存在するかどうかを確認する。ファイルが存在しない場合falseをリターンする。
  • hash(filepath: string, algorithm: string): パラメータのファイル位置のファイルの当該アルゴリズム(algorithem)のchecksumをリターンする。アルゴリズム(algorithm)はmd5, sha1, sha224, sha256, sha384, sha512が使える。
  • touch(filepath: string, mtime?: Date, ctime?: Date): ファイルの修正日(mtime)と生成日(ctime)を更新する。iOSでは生成日(ctime)のみで修正が可能ですが、アンドロイドは修正日(mtime)を使って修正日と生成日をいつも同時に更新する。
  • mkdir(filepath: string, options?: MkdirOptions): フォルダを生成する。
  • downloadFile(options: DownloadFileOptions): パラメータのオプション(options)中のファイルURLを使ってファイルをダウンロードする。
  • stopDownload(jobId: number): パラメータのダウンロードidを使ってダウンロードを中止する。
  • getFSInfo(): ファイルシステムの情報(総容量、使える容量)をリターンする。

iOS専用

下記のリストはreact-native-fsでiOSのみで使える機能です。

  • copyAssetsFileIOS(imageUri: string, destPath: string, width: number, height: number, scale : number = 1.0, compression : number = 1.0, resizeMode : string = ‘contain’ ): (iOS) iOSのカメラロール(Camera-roll)に存在するファイルをコピします。
  • resumeDownload(jobId: number): (iOS) パラメータのダウンロードidを使ってダウンロードを再開します。
  • isResumable(jobId: number): (iOS) パラメータのダウンロードidが再開できるかどうか確認します。
  • completeHandlerIOS(jobId: number): (iOS) バックグラウンドでダウンロードする時ダウンロードが終わったことを知らせるように設定することが可能です。
  • uploadFiles(options: UploadFileOptions): (iOS) ファイルをアップロードします。
  • stopUpload(jobId: number): (iOS) ファイルアップロードを中止します。
  • pathForGroup(groupIdentifier: string): (iOS) iOSで com.apple.security.application-groupsに設定した全てのものをリターンします。

アンドロイド専用

下記のリストはreact-native-fsでアンドロイド(Android)のみで使える機能です。

  • existsAssets(filepath: string): (アンドロイド) アンドロイドのassetsフォルダにファイルが存在するかどうかを確認する。ファイルが存在しない場合falseをリターンします。
  • readFileAssets(filepath:string, encoding?: string): (アンドロイド) アンドロイドのassetsフォルダ下にあるファイルをファイル位置を使って読む。
  • copyFileAssets(filepath: string, destPath: string): (アンドロイド) ファイルをアンドロイドのassetsフォルダ下にコピする。
  • readDirAssets(dirpath: string): (アンドロイド) パラメータで貰ったアンドロイドのassetsフォルダ下の相対位置(Relative path)の内容を読む。
  • scanFile(path: string): (アンドロイド) Media Scannerを使ってファイルをスキャン(scan)する
  • getAllExternalFilesDirs(): (アンドロイド) 全ての共有/外部ストレージの情報をリターンする。

完了

リアクトネイティブ(React Native)でファイルシステムを使う場合react-native-fsを使えることをお勧めします。OSに依存する機能もありますが、大体共通機能でも十分活用できます。リターンバリュー(Return Value)とパラメータ(Parameter)に関する詳しく説明はいませんでした。リターンバリュー(Return Value)とパラメータ(Parmeter)に関する内容は公式サイトを参考してください。

参考

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts