Template version: v0.2.2
[!TIP] GitHub address
Find the matching version information in the release address of a third-party library: @react-native-oh-tpl/react-native-file-access Releases.For older versions that are not published to npm, please refer to the installation guide to install the tgz package.
Go to the project directory and execute the following instruction:
npm install @react-native-oh-tpl/react-native-file-accessyarn add @react-native-oh-tpl/react-native-file-accessThe following code shows the basic use scenario of the repository:
[!WARNING] The name of the imported repository remains unchanged.
[!TIP] 以下 demo 中使用的是本地文件。
import React, { useEffect, useState } from 'react';
import { Button, SafeAreaView, ScrollView, StyleSheet, Text, View } from 'react-native';
import { Dirs, FileSystem } from 'react-native-file-access';
export function FileAccessDemo() {
const [info, setInfo] = useState<{ key: string; value: string }[]>([]);
const [result, setResult] = useState<string | null>('') || null;
const [fileContent, setFileContent] = useState('');
const [mkdirParam, setMkdirParam] = useState('');
const [statInfo, setStatInfo] = useState<any>([]);
const [isExists, setExists] = useState<boolean | string>('');
const [lsList, setLsList] = useState<any>([]);
const [totalSize, setTotalSize] = useState<number>();
const [freeSize, setFreeSize] = useState<number>();
const [hashValue, setHashValue] = useState<string>();
const [statDirInfo, setStatDirInfo] = useState<object[]>([]);
const [readFileChunkInfo, setReadFileChunkInfo] = useState<string>();
const [concatBeyts, setConcatBeyts] = useState<number>();
const [dirOrNot, setDirOrNot] = useState<any>('');
const wirteFile = () => {
FileSystem.writeFile(Dirs.DocumentDir + '/0801' + '/text1.txt', "DDDD", "utf8")
};
const readFile = () => {
FileSystem.readFile(Dirs.DocumentDir + "/0801.txt").then((res) => {
setFileContent(res);
})
};
const unlink = () => {
FileSystem.unlink(Dirs.DocumentDir + '/0812.txt');
};
const mkdir = () => {
FileSystem.mkdir(Dirs.DocumentDir + "/wxwx").then((res) => {
setMkdirParam(res);
}).catch((error) => {
console.log(error, 'error')
});
};
const mv = () => {
FileSystem.mv(Dirs.DocumentDir + "/text.txt", Dirs.DocumentDir + "/text1.txt");
};
const unzip = () => {
FileSystem.unzip(Dirs.DocumentDir + "/wxwx.zip", Dirs.DocumentDir);
};
const stat = () => {
FileSystem.stat(Dirs.DocumentDir + "/text1.txt").then((res) => {
setStatInfo(JSON.stringify(res));
}).catch(err => {
console.log(err);
})
};
const exists = () => {
FileSystem.exists(Dirs.DocumentDir + "/text1.txt").then((res) => {
setExists(res);
}).catch((error) => {
console.log(error, 'error');
});
};
const cp = async () => {
await FileSystem.cp(Dirs.DocumentDir + "/text1.txt", Dirs.DocumentDir + "/text4.txt")
};
const hash = () => {
FileSystem.hash(Dirs.DocumentDir + "/text1.txt", 'SHA-256').then((res) => {
setHashValue(res);
}).catch((error) => {
console.log(error, 'error')
});
};
const isDir = async () => {
let res = await FileSystem.isDir(Dirs.DocumentDir + '/text1.txt');
setDirOrNot(res);
};
const ls = async () => {
await FileSystem.ls(Dirs.DocumentDir).then((res) => {
setLsList(res.join('、'));
}).catch((error) => {
console.log(error, 'error')
});
};
const df = async () => {
await FileSystem.df().then(res => {
setFreeSize(res?.internal_free);
setTotalSize(res?.internal_total);
})
};
const statDir = () => {
FileSystem.statDir(Dirs.DocumentDir).then(res => {
setStatDirInfo(res);
}).catch(err => {
console.log(err);
});
};
const readFileChunk = () => {
FileSystem.readFileChunk(Dirs.DocumentDir + "/text2.txt", 1, 1, 'utf8').then((res) => {
setReadFileChunkInfo(res);
}).catch((error) => {
console.log(error, 'error')
});
};
const appendFile = async () => {
await FileSystem.appendFile(Dirs.DocumentDir + "/text3.txt", "AAAAAA", 'utf8');
}
const concatFiles = async () => {
await FileSystem.concatFiles(Dirs.DocumentDir + "/text3.txt", Dirs.DocumentDir + "/text4.txt").then((res) => {
setConcatBeyts(res)
}).catch((error) => {
console.log(error, 'error')
});
};
return (
<ScrollView>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.wirteFile()</Text>
<Button title=" Running" color="#841584" onPress={wirteFile}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.readFile()</Text>
<Button title=" Running" color="#841584" onPress={readFile}></Button>
</View>
<Text>read the file contents: {fileContent}</Text>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.unlink()</Text>
<Button title=" Running" color="#841584" onPress={unlink}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.mkdir()</Text>
<Button title=" Running" color="#841584" onPress={mkdir}></Button>
</View>
<Text>new directory path: {mkdirParam}</Text>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.mv()</Text>
<Button title=" Running" color="#841584" onPress={mv}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.stat()</Text>
<Button title=" Running" color="#841584" onPress={stat}></Button>
</View>
<Text>file information: {statInfo}</Text>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.exists()</Text>
<Button title=" Running" color="#841584" onPress={exists}></Button>
</View>
<Text>does the file exist: {isExists === '' ? '' : isExists ? 'exist' : 'does not exist'}</Text>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.cp()</Text>
<Button title=" Running" color="#841584" onPress={cp}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.isDir()</Text>
<Button title=" Running" color="#841584" onPress={isDir}></Button>
</View>
<Text>is it a directory: {dirOrNot === '' ? '' : dirOrNot ? 'yes' : 'no'}</Text>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.ls()</Text>
<Button title=" Running" color="#841584" onPress={ls}></Button>
</View>
<Text>files in the directory: {lsList}</Text>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.df()</Text>
<Button title=" Running" color="#841584" onPress={df}></Button>
</View>
<Text>available space: {freeSize ? (freeSize / (1024 * 1024 * 1024)).toFixed(2) : ''}GB</Text>
<Text>total space: {totalSize ? (totalSize / (1024 * 1024 * 1024)).toFixed(2) : ''}GB</Text>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.hash()</Text>
<Button title=" Running" color="#841584" onPress={hash}></Button>
</View>
<Text>hash value: {hashValue}</Text>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.unzip()</Text>
<Button title=" Running" color="#841584" onPress={unzip}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.statDir()</Text>
<Button title=" Running" color="#841584" onPress={statDir}></Button>
</View>
<Text>the following is the file information in the directory</Text>
{statDirInfo.map((item, index) => (<Text key={index}>{JSON.stringify(item)}</Text>))}
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.readFileChunk()</Text>
<Button title=" Running" color="#841584" onPress={readFileChunk}></Button>
</View>
<Text>read part of the file content: {readFileChunkInfo}</Text>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.appendFile()</Text>
<Button title=" Running" color="#841584" onPress={appendFile}></Button>
</View>
<View style={{ height: 'auto', backgroundColor: "#FFF", marginTop: 6 }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>FileAccess.concatFiles()</Text>
<Button title=" Running" color="#841584" onPress={concatFiles}></Button>
</View>
<Text>number of bytes written: {concatBeyts}</Text>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
key: { flex: 1.5, padding: 2 },
row: { flexDirection: 'row', paddingVertical: 2 },
value: { flex: 4, padding: 2 },
baseArea: {
width: "100%",
height: 60,
borderRadius: 4,
borderColor: "#000000",
marginTop: 6,
backgroundColor: "#FFFFFF",
flexDirection: "row",
alignItems: "center",
paddingLeft: 8,
paddingRight: 8,
},
});If this repository has been adapted to Codegen, generate the bridge code of the third-party library by using the Codegen. For details, see Codegen Usage Guide.
Currently, HarmonyOS does not support AutoLink. Therefore, you need to manually configure the linking.
Open the harmony directory of the HarmonyOS project in DevEco Studio.
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}
Currently, two methods are available:
Method 1 (recommended): Use the HAR file.
[!TIP] The HAR file is stored in the
harmonydirectory in the installation path of the third-party library.
Open entry/oh-package.json5 file and add the following dependencies:
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@react-native-oh-tpl/react-native-file-access": "file:../../node_modules/@react-native-oh-tpl/react-native-file-access/harmony/file_access.har"
}Click the sync button in the upper right corner.
Alternatively, run the following instruction on the terminal:
cd entry
ohpm installMethod 2: Directly link to the source code.
[!TIP] For details, see Directly Linking Source Code.
Open the entry/src/main/ets/RNPackagesFactory.ts file and add the following code:
...
+ import { RNFileAccessPackage } from '@react-native-oh-tpl/react-native-file-access/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SamplePackage(ctx),
+ new RNFileAccessPackage(ctx)
];
}Click the sync button in the upper right corner.
Alternatively, run the following instruction on the terminal:
cd entry
ohpm installThen build and run the code.
To use this repository, you need to use the correct React-Native and RNOH versions. In addition, you need to use DevEco Studio and the ROM on your phone.
Check the release version information in the release address of the third-party library: @react-native-oh-tpl/react-native-file-access Releases
[!TIP] The Platform column indicates the platform where the properties are supported in the original third-party library.。
[!TIP] If the value of HarmonyOS Support is yes, it means that the HarmonyOS platform supports this property; no means the opposite; partially means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android.
| Name | Description | Type | Platform | Required | HarmonyOS Support |
|---|---|---|---|---|---|
| appendFile | Append content to a file. | Function | No | iOS/Android | Yes |
| concatFiles | Append a file to another file. Returns number of bytes written. | Function | No | iOS/Android | Yes |
| cp | Copy a file. | Function | No | iOS/Android | Yes |
| cpAsset | Copy a bundled asset file. | Function | No | iOS/Android | Yes |
| cpExternal | Copy a file to an externally controlled location. | Function | No | iOS/Android | Yes |
| df | Check device available space. | Function | No | iOS/Android | Yes |
| exists | Check if a path exists. | Function | No | iOS/Android | Yes |
| fetch | Save a network request to a file. | Function | No | iOS/Android | Yes |
| getAppGroupDir | Get the directory for your app group (iOS & MacOS only). | Function | No | iOS | No |
| hash | Hash the file content. | Function | No | iOS/Android | Yes |
| isDir | Check if a path is a directory. | Function | No | iOS/Android | Yes |
| ls | List files in a directory. | Function | No | iOS/Android | Yes |
| mkdir | Make a new directory. | Function | No | iOS/Android | Yes |
| mv | Move a file. | Function | No | iOS/Android | Yes |
| readFile | Read the content of a file. | Function | No | iOS/Android | Yes |
| readFileChunk | Read a chunk of the content of a file, starting from byte at offset, reading for length bytes. | Function | No | iOS/Android | Yes |
| stat | Read file metadata. | Function | No | iOS/Android | Yes |
| statDir | Read metadata of all files in a directory. | Function | No | iOS/Android | Yes |
| unlink | Delete a file. | Function | No | iOS/Android | Yes |
| unzip | Extract a zip archive. | Function | No | iOS/Android | Yes |
| writeFile | Write content to a file. | Function | No | iOS/Android | Yes |
- getAppGroupDir method (Get application directory permissions, iOS, Mac iOS only) This is a dependency problem. Currently, the Harmony side does not provide support. issue#4
This project is licensed under The MIT License (MIT).