1# Accessing Application Files (ArkTS)
2
3This topic describes how to enable an application to view, create, read, write, delete, move, or copy an application file and obtain file information.
4
5## Available APIs
6
7You can use [ohos.file.fs](../reference/apis-core-file-kit/js-apis-file-fs.md) to implement access to application files. The following table describes the commonly used APIs.
8
9**Table 1** APIs for basic application file operations
10
11| API| Description| Category| Synchronous Programming| Asynchronous Programming|
12| -------- | -------- | -------- | -------- | -------- |
13| access | Checks whether a file exists.| Method| Supported| Supported|
14| close | Closes a file.| Method| Supported| Supported|
15| copyFile | Copies a file.| Method| Supported| Supported|
16| createStream | Creates a stream based on a file path.| Method| Supported| Supported|
17| listFile | Lists all files in a directory.| Method| Supported| Supported|
18| mkdir | Creates a directory.| Method| Supported| Supported|
19| moveFile | Moves a file.| Method| Supported| Supported|
20| open | Opens a file.| Method| Supported| Supported|
21| read | Reads data from a file.| Method| Supported| Supported|
22| rename | Renames a file or folder.| Method| Supported| Supported|
23| rmdir | Deletes a directory.| Method| Supported| Supported|
24| stat | Obtains detailed file information.| Method| Supported| Supported|
25| unlink | Deletes a single file.| Method| Supported| Supported|
26| write | Writes data to a file.| Method| Supported| Supported|
27| Stream.close | Closes a stream.| Method| Supported| Supported|
28| Stream.flush | Flushes all data from this stream.| Method| Supported| Supported|
29| Stream.write | Writes data to a stream.| Method| Supported| Supported|
30| Stream.read | Reads data from a stream.| Method| Supported| Supported|
31| File.fd | Defines a file descriptor.| Attribute| N/A| N/A|
32| OpenMode | Defines the mode for opening a file.| Attribute| N/A| N/A|
33| Filter | Defines the options for filtering files.| Type| N/A| N/A|
34
35> **NOTE**
36>
37> When using ohos.file.fs APIs, you are advised to use asynchronous APIs for time-consuming operations, such as read and write operations, to prevent application crashes.
38
39## Development Example
40
41Before performing any file operation, obtain the [application file path](../application-models/application-context-stage.md#obtaining-application-file-paths). The following example shows how to obtain a HAP file path using **UIAbilityContext**. For details about how to obtain **UIAbilityContext**, see [Obtaining the Context of UIAbility](../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
42
43The following walks you through on how to perform common file operations.
44
45### Creating, Reading, and Writing a File
46
47The following example demonstrates how to create a file, read data from it, and write data to it.
48
49```ts
50// pages/xxx.ets
51import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
52import { common } from '@kit.AbilityKit';
53import { buffer } from '@kit.ArkTS';
54
55// Obtain the application file path.
56let context = getContext(this) as common.UIAbilityContext;
57let filesDir = context.filesDir;
58
59function createFile(): void {
60  // Create a file and open it.
61  let file = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
62  // Write data to the file.
63  let writeLen = fs.writeSync(file.fd, "Try to write str.");
64  console.info("The length of str is: " + writeLen);
65  // Read data from the file.
66  let arrayBuffer = new ArrayBuffer(1024);
67  let readOptions: ReadOptions = {
68    offset: 0,
69    length: arrayBuffer.byteLength
70  };
71  let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
72  let buf = buffer.from(arrayBuffer, 0, readLen);
73  console.info("the content of file: " + buf.toString());
74  // Close the file.
75  fs.closeSync(file);
76}
77```
78
79### Copying Data to Another File
80
81The following example demonstrates how to read data from a file and copy it to another file.
82
83```ts
84// pages/xxx.ets
85import { fileIo as fs, ReadOptions, WriteOptions } from '@kit.CoreFileKit';
86import { common } from '@kit.AbilityKit';
87
88// Obtain the application file path.
89let context = getContext(this) as common.UIAbilityContext;
90let filesDir = context.filesDir;
91
92function readWriteFile(): void {
93  // Open the source and destination files.
94  let srcFile = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
95  let destFile = fs.openSync(filesDir + '/destFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
96  // Read data from the source file and copy it to the destination file.
97  let bufSize = 4096;
98  let readSize = 0;
99  let buf = new ArrayBuffer(bufSize);
100  let readOptions: ReadOptions = {
101    offset: readSize,
102    length: bufSize
103  };
104  let readLen = fs.readSync(srcFile.fd, buf, readOptions);
105  while (readLen > 0) {
106    readSize += readLen;
107    let writeOptions: WriteOptions = {
108      length: readLen
109    };
110    fs.writeSync(destFile.fd, buf, writeOptions);
111    readOptions.offset = readSize;
112    readLen = fs.readSync(srcFile.fd, buf, readOptions);
113  }
114  // Close the files.
115  fs.closeSync(srcFile);
116  fs.closeSync(destFile);
117}
118```
119
120> **NOTE**
121>
122> When using **read()** or **write()**, pay attention to the optional parameter **offset**. For a file that has been read or written, **offset** points to the end position of the last read or write operation by default.
123
124### Reading and Writing Files in a Stream
125
126The following example demonstrates how to read and write file data using a stream.
127
128```ts
129// pages/xxx.ets
130import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
131import { common } from '@kit.AbilityKit';
132
133// Obtain the application file path.
134let context = getContext(this) as common.UIAbilityContext;
135let filesDir = context.filesDir;
136
137async function readWriteFileWithStream(): Promise<void> {
138  // Open the file streams.
139  let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
140  let outputStream = fs.createStreamSync(filesDir + '/destFile.txt', "w+");
141  // Read data from the source file and write the data to the destination file using a stream.
142  let bufSize = 4096;
143  let readSize = 0;
144  let buf = new ArrayBuffer(bufSize);
145  let readOptions: ReadOptions = {
146    offset: readSize,
147    length: bufSize
148  };
149  let readLen = await inputStream.read(buf, readOptions);
150  readSize += readLen;
151  while (readLen > 0) {
152    const writeBuf = readLen < bufSize ? buf.slice(0, readLen) : buf;
153    await outputStream.write(writeBuf);
154    readOptions.offset = readSize;
155    readLen = await inputStream.read(buf, readOptions);
156    readSize += readLen;
157  }
158  // Close the streams.
159  inputStream.closeSync();
160  outputStream.closeSync();
161}
162```
163
164> **NOTE**
165>
166> - Close the stream once it is not required.
167> - Comply with the programming specifications for **Stream** APIs in asynchronous mode and avoid mixed use of the APIs in synchronous mode and asynchronous mode.
168> - The **Stream** APIs do not support concurrent read and write operations.
169
170### Listing Files
171
172The following example demonstrates how to obtain files that meet the specified conditions.
173
174```ts
175import { fileIo as fs, Filter, ListFileOptions } from '@kit.CoreFileKit';
176import { common } from '@kit.AbilityKit';
177
178// Obtain the application file path.
179let context = getContext(this) as common.UIAbilityContext;
180let filesDir = context.filesDir;
181
182// List files that meet the specified conditions.
183function getListFile(): void {
184  let listFileOption: ListFileOptions = {
185    recursion: false,
186    listNum: 0,
187    filter: {
188      suffix: [".png", ".jpg", ".txt"],
189      displayName: ["test*"],
190      fileSizeOver: 0,
191      lastModifiedAfter: new Date(0).getTime()
192    }
193  };
194  let files = fs.listFileSync(filesDir, listFileOption);
195  for (let i = 0; i < files.length; i++) {
196    console.info(`The name of file: ${files[i]}`);
197  }
198}
199```
200
201### Using File Streams
202
203The following example demonstrates how to use readable and writable streams.
204
205```ts
206// pages/xxx.ets
207import { fileIo as fs } from '@kit.CoreFileKit';
208import { common } from '@kit.AbilityKit';
209
210// Obtain the application file path.
211let context = getContext(this) as common.UIAbilityContext;
212let filesDir = context.filesDir;
213
214function copyFileWithReadable(): void {
215  // Create a readable stream.
216  const rs = fs.createReadStream(`${filesDir}/read.txt`);
217  // Create a writable stream.
218  const ws = fs.createWriteStream(`${filesDir}/write.txt`);
219  // Copy files in paused mode.
220  rs.on('readable', () => {
221    const data = rs.read();
222    if (!data) {
223      return;
224    }
225    ws.write(data);
226  });
227}
228
229function copyFileWithData(): void {
230  // Create a readable stream.
231  const rs = fs.createReadStream(`${filesDir}/read.txt`);
232  // Create a writable stream.
233  const ws = fs.createWriteStream(`${filesDir}/write.txt`);
234  // Copy files in flowing mode.
235  rs.on('data', (emitData) => {
236    const data = emitData?.data;
237    if (!data) {
238      return;
239    }
240    ws.write(data as Uint8Array);
241  });
242}
243
244```
245
246The following example demonstrates how to use a file hash stream.
247
248```ts
249// pages/xxx.ets
250import { fileIo as fs } from '@kit.CoreFileKit';
251import { hash } from '@kit.CoreFileKit';
252import { common } from '@kit.AbilityKit';
253
254// Obtain the application file path.
255let context = getContext(this) as common.UIAbilityContext;
256let filesDir = context.filesDir;
257
258function hashFileWithStream() {
259  const filePath = `${filesDir}/test.txt`;
260  // Create a readable stream.
261  const rs = fs.createReadStream(filePath);
262  // Create a hash stream.
263  const hs = hash.createHash('sha256');
264  rs.on('data', (emitData) => {
265    const data = emitData?.data;
266    hs.update(new Uint8Array(data?.split('').map((x: string) => x.charCodeAt(0))).buffer);
267  });
268  rs.on('close', async () => {
269    const hashResult = hs.digest();
270    const fileHash = await hash.hash(filePath, 'sha256');
271    console.info(`hashResult: ${hashResult}, fileHash: ${fileHash}`);
272  });
273}
274
275```
276