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## Development Example
36
37Before 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).
38
39The following walks you through on how to perform common file operations.
40
41### Creating, Reading, and Writing a File
42
43The following example demonstrates how to create a file, read data from it, and write data to it.
44
45```ts
46// pages/xxx.ets
47import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
48import { common } from '@kit.AbilityKit';
49import { buffer } from '@kit.ArkTS';
50
51// Obtain the application file path.
52let context = getContext(this) as common.UIAbilityContext;
53let filesDir = context.filesDir;
54
55function createFile(): void {
56  // Create a file and open it.
57  let file = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
58  // Write data to the file.
59  let writeLen = fs.writeSync(file.fd, "Try to write str.");
60  console.info("The length of str is: " + writeLen);
61  // Read data from the file.
62  let arrayBuffer = new ArrayBuffer(1024);
63  let readOptions: ReadOptions = {
64    offset: 0,
65    length: arrayBuffer.byteLength
66  };
67  let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
68  let buf = buffer.from(arrayBuffer, 0, readLen);
69  console.info("the content of file: " + buf.toString());
70  // Close the file.
71  fs.closeSync(file);
72}
73```
74
75### Copying Data to Another File
76
77The following example demonstrates how to read data from a file and copy it to another file.
78
79```ts
80// pages/xxx.ets
81import { fileIo as fs, ReadOptions, WriteOptions } from '@kit.CoreFileKit';
82import { common } from '@kit.AbilityKit';
83
84// Obtain the application file path.
85let context = getContext(this) as common.UIAbilityContext;
86let filesDir = context.filesDir;
87
88function readWriteFile(): void {
89  // Open the source and destination files.
90  let srcFile = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
91  let destFile = fs.openSync(filesDir + '/destFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
92  // Read data from the source file and copy it to the destination file.
93  let bufSize = 4096;
94  let readSize = 0;
95  let buf = new ArrayBuffer(bufSize);
96  let readOptions: ReadOptions = {
97    offset: readSize,
98    length: bufSize
99  };
100  let readLen = fs.readSync(srcFile.fd, buf, readOptions);
101  while (readLen > 0) {
102    readSize += readLen;
103    let writeOptions: WriteOptions = {
104      length: readLen
105    };
106    fs.writeSync(destFile.fd, buf, writeOptions);
107    readOptions.offset = readSize;
108    readLen = fs.readSync(srcFile.fd, buf, readOptions);
109  }
110  // Close the files.
111  fs.closeSync(srcFile);
112  fs.closeSync(destFile);
113}
114```
115
116> **NOTE**
117>
118> 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.
119
120### Reading and Writing Files in a Stream
121
122The following example demonstrates how to read and write file data using a stream.
123
124```ts
125// pages/xxx.ets
126import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
127import { common } from '@kit.AbilityKit';
128
129// Obtain the application file path.
130let context = getContext(this) as common.UIAbilityContext;
131let filesDir = context.filesDir;
132
133async function readWriteFileWithStream(): Promise<void> {
134  // Open the file streams.
135  let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
136  let outputStream = fs.createStreamSync(filesDir + '/destFile.txt', "w+");
137  // Read data from the source file and write the data to the destination file using a stream.
138  let bufSize = 4096;
139  let readSize = 0;
140  let buf = new ArrayBuffer(bufSize);
141  let readOptions: ReadOptions = {
142    offset: readSize,
143    length: bufSize
144  };
145  let readLen = await inputStream.read(buf, readOptions);
146  readSize += readLen;
147  while (readLen > 0) {
148    const writeBuf = readLen < bufSize ? buf.slice(0, readLen) : buf;
149    await outputStream.write(writeBuf);
150    readOptions.offset = readSize;
151    readLen = await inputStream.read(buf, readOptions);
152    readSize += readLen;
153  }
154  // Close the streams.
155  inputStream.closeSync();
156  outputStream.closeSync();
157}
158```
159
160> **NOTE**
161>
162> - Close the stream once it is not required.
163> - Comply with the programming specifications for **Stream** APIs in asynchronous mode and avoid mixed use of the APIs in synchronous mode and asynchronous mode. 
164> - The **Stream** APIs do not support concurrent read and write operations.
165
166### Listing Files
167
168The following example demonstrates how to list files that meet the specified conditions.
169
170```ts
171import { fileIo as fs, Filter, ListFileOptions } from '@kit.CoreFileKit';
172import { common } from '@kit.AbilityKit';
173
174// Obtain the application file path.
175let context = getContext(this) as common.UIAbilityContext;
176let filesDir = context.filesDir;
177
178// List files that meet the specified conditions.
179function getListFile(): void {
180  let listFileOption: ListFileOptions = {
181    recursion: false,
182    listNum: 0,
183    filter: {
184      suffix: [".png", ".jpg", ".txt"],
185      displayName: ["test*"],
186      fileSizeOver: 0,
187      lastModifiedAfter: new Date(0).getTime()
188    }
189  };
190  let files = fs.listFileSync(filesDir, listFileOption);
191  for (let i = 0; i < files.length; i++) {
192    console.info(`The name of file: ${files[i]}`);
193  }
194}
195```
196
197### Using File Streams
198
199The following sample code demonstrates how to use readable and writable streams.
200
201```ts
202// pages/xxx.ets
203import { fileIo as fs } from '@kit.CoreFileKit';
204import { common } from '@kit.AbilityKit';
205
206// Obtain the application file path.
207let context = getContext(this) as common.UIAbilityContext;
208let filesDir = context.filesDir;
209
210function copyFileWithReadable(): void {
211  // Create a readable stream.
212  const rs = fs.createReadStream(`${filesDir}/read.txt`);
213  // Create a writable stream.
214  const ws = fs.createWriteStream(`${filesDir}/write.txt`);
215  // Copy files in paused mode. 
216  rs.on('readable', () => {
217    const data = rs.read();
218    if (!data) {
219      return;
220    }
221    ws.write(data);
222  });
223}
224
225function copyFileWithData(): void {
226  // Create a readable stream.
227  const rs = fs.createReadStream(`${filesDir}/read.txt`);
228  // Create a writable stream.
229  const ws = fs.createWriteStream(`${filesDir}/write.txt`);
230  // Copy files in flowing mode.
231  rs.on('data', (emitData) => {
232    const data = emitData?.data;
233    if (!data) {
234      return;
235    }
236    ws.write(data as Uint8Array);
237  });
238}
239
240```
241
242The following code demonstrates how to use a file hash stream.
243
244```ts
245// pages/xxx.ets
246import { fileIo as fs } from '@kit.CoreFileKit';
247import { hash } from '@kit.CoreFileKit';
248import { common } from '@kit.AbilityKit';
249
250// Obtain the application file path.
251let context = getContext(this) as common.UIAbilityContext;
252let filesDir = context.filesDir;
253
254function hashFileWithStream() {
255  const filePath = `${filesDir}/test.txt`;
256  // Create a readable stream.
257  const rs = fs.createReadStream(filePath);
258  // Create a hash stream.
259  const hs = hash.createHash('sha256');
260  rs.on('data', (emitData) => {
261    const data = emitData?.data;
262    hs.update(new Uint8Array(data?.split('').map((x: string) => x.charCodeAt(0))).buffer);
263  });
264  rs.on('close', async () => {
265    const hashResult = hs.digest();
266    const fileHash = await hash.hash(filePath, 'sha256');
267    console.info(`hashResult: ${hashResult}, fileHash: ${fileHash}`);
268  });
269}
270
271```
272