react-native-fs: RNFS.writeFile() -> ENOENT: open failed: EEXIST (File exists) - if file is deleted manually

On a real Android device, RNFS.writeFile() fails saying ENOENT: open failed: EEXIST (File exists), while RNFS.exists() returns false. This occurs after the file was created by the app, and then deleted manually from the file system. This problem does NOT occur on an Android emulator.

Scenario to reproduce: ON A REAL DEVICE:

  1. Use RNFS.writeFile() to create a file
  2. Using a file access software, e.g. Google Files, delete the created file (above).
  3. Try to re-create the file again using RNFS.writeFile()
  4. You get an error ENOENT: open failed: EEXIST (File exists), while it has been deleted, and the result of RNFS.exists() confirms that it is not there?!

Device Infomation:

Samsung Galaxy S10+ 
Android Version: 11
One UI Version: 3.1
Google Play system update: 1 August 2021
Kernel version: 4.14.113.22340597
#1 Wed Dec 1 11:14:06  KST 2021 

Code:

try {
	const fileExists = await RNFS.exists(fullPath); 
	console.log("fileExists:", fileExists, "fullPath:", fullPath, ); // fileExists: false  - fullPath: /storage/emulated/0/Download/myFileName.csv

	if (fileExists) {
                // Execution never reaches this point 
                console.log("inside if statement", ); 
		await RNFS.unlink(fullPath); 
		console.log("file deleted");
	}

        // The following statement triggers the catch (below) 
	await RNFS.writeFile(fullPath, fileContents, "utf8");

	// execution never reaches this point 
	console.log("file Written");
}
catch (err) {
	console.error("err:", err ); //  err: [Error: ENOENT: open failed: EEXIST (File exists), open '/storage/emulated/0/Download/myFileName.csv']
}

Versions:

    "react-native": "0.66.4",
    "react-native-fs": "^2.18.0",

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 4
  • Comments: 15

Most upvoted comments

Fixed by this way:

  1. add to the AndroidManifest.xml
<application android:requestLegacyExternalStorage="true"`
  1. request permission:
const requestWritePermission = async () => {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
    );
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log('You can use the write');
      return true;
    } else {
      console.log('write denied');
      return false;
    }
  } catch (err) {
    Alert.alert(err.message);
    return false;
  }
};

I believe that android caches the filenames even after you delete them. I have Android File Manager and when I delete a file through there and close the app I am able to save the file with the same name successfully. If I delete the file from the file manager on the device and try to resave with the same name then it throws the “already exists” error.