react-native-fs
react-native-fs copied to clipboard
`writeFile` on Android Simulator will not overwrite an existing file, but write over it
I am using the RNFS.writeFile(path, myObject, 'utf8');
method to write on a file specified by path
. It works perfectly on iOS, but on Android Simulator it behaves strangely. When I use the command to write on a file that already exists, it will not completely overwrite the existing file, but it will write over it, keeping the existing content/string. The consequence is that if the existing file has a longer string than the string I am trying to write, the end of the string will be a broken thing, very weird.
I have tried to do exists()
and unlink()
in case the file exists before writing and it eliminates the bug. But the app becomes slower and if the user writes too fast I get some other annoying bugs because file does not exists when I try to read it.
Did anyone else had the same trouble as me?
Finally, I solved the issue by ditching react-native-fs
and using rn-fetch-blob
instead. I couldn't afford to wait for the issue in this lib to be fixed. Hope the issue will be investigated anyway.
@pedrosimao I am experiencing a similar issue but only on Android Q (API 29), on older versions it looks fine, could you tell which version were you using, so we could narrow down the problem?
@pedrosimao @gpawlik Just running into this now as well on Android Q. Any luck with it?
Occurring for me as well. Pixel 2, Android 10, physical device.
I am not a developer, but this sounds like the same behaviour I see in the Joplin Android app when using local storage sync on Android 10.
Whenever I delete information from a note, the same number of characters stay appended to the end of the file, causing the sync process to fail.
I have an original Pixel XL and a Pixel 3a XL, both running Android 10.
Same issue here with production app, all devices running Android 10 - not writing over the whole file, but only the part that overlaps - i.e. if I want to write 100 symbols to a 120-symbol file, only the first 100 are overwritten and the rest remain, which in my case break the app. Devices include Samsung Note-s, OnePlus, Nokia, Huawei etc. all that have A10 updated. Might be a change in the the Android 10 API that is used in this package.
The fix that I used, because I really needed to fix the production was - with each write, first delete the file:
RNFS.unlink(path).then(() => { RNFS.writeFile(path, content)); });
It is dirty as hell, and not really sure what the performance hit is, but it works, at least to patch the production app.
I forgot to mention that in order to be safe when using this hacky workaround, I added an async queue to adapter that I am using for writing the files - meaning that a second write would not start executing before the unlink and write are finalized (in order to eliminate the race condition).
And that is acceptable in my case when I am doing rare writes to very few files.
I am also encountering this issue in our production app, only in Android 10. previous android versions work fine.
I am wondering if it is to do with this line in RNFSManager.java
getOutputStream
method:
stream = reactContext.getContentResolver().openOutputStream(uri, append ? "wa" : "w");
according to documentation, the 'w' access mode passed as the second parameter of openOutputStream is supposed to give "write-only access (erasing whatever data is currently in the file)"
Another access mode option listed in the documentation is "rwt" which gives: "read and write access that truncates any existing file" So I replaced "w" with "rwt":
stream = reactContext.getContentResolver().openOutputStream(uri, append ? "wa" : "rwt");
From my limited tests, this change appears to work, it overwrites the file, and does not leave the extra trailing data.
Can anyone else give their opinion/insight on this? I am not completely familiar with Android and Java and file I/O.
Found this issue on the android bug tracker: https://issuetracker.google.com/issues/135714729 They confirm that in order to truncate the file, you need to pass "t" in the access mode
I found this issue on Actual Device as well. It just creates random pdf of existing file and new data.
Couldn't wait for react-native-fs to release a new version (greater than 2.18.0), so i pushed a new npm package with the latest code from react-native-fs into react-native-fs-rwt
I think this can be closed now as it seems to have been fixed in a recent version: https://github.com/itinance/react-native-fs/blob/master/android/src/main/java/com/rnfs/RNFSManager.java#L118-L126 Notice that it's now using "wrt" depending on Android version.
This was released in version 2.20.0: https://github.com/itinance/react-native-fs/commit/b7c7bf03481ee4f74f80cceb843267c05e9a3b9c
@pedrosimao should we close?
This is still an issue for me on 2.20.0. On ios it works fine, but android the file does not overwrite