@@ -25,6 +25,7 @@ import java.io.OutputStream
2525import java.lang.ref.WeakReference
2626import java.security.MessageDigest
2727import java.util.zip.ZipInputStream
28+ import java.nio.file.Files
2829
2930class FileAccessModule internal constructor(context : ReactApplicationContext ) :
3031 FileAccessSpec (context) {
@@ -275,6 +276,40 @@ class FileAccessModule internal constructor(context: ReactApplicationContext) :
275276 promise.reject(" ERR" , " App group unavailable on Android." )
276277 }
277278
279+ @ReactMethod
280+ override fun hardlink (source : String , target : String , promise : Promise ) {
281+ ioScope.launch {
282+ try {
283+ if (source.isContentUri() || target.isContentUri()) {
284+ promise.reject(" ERR" , " Hard links are not supported for content URIs" )
285+ return @launch
286+ }
287+
288+ val sourceFile = parsePathToFile(source)
289+ val targetFile = parsePathToFile(target)
290+
291+ if (! sourceFile.exists()) {
292+ promise.reject(" ENOENT" , " Source file '$source ' does not exist" )
293+ return @launch
294+ }
295+
296+ if (targetFile.exists()) {
297+ promise.reject(" EEXIST" , " Target file '$target ' already exists" )
298+ return @launch
299+ }
300+
301+ try {
302+ Files .createLink(targetFile.toPath(), sourceFile.toPath())
303+ promise.resolve(null )
304+ } catch (e: IOException ) {
305+ promise.reject(" ERR" , " Failed to create hard link: ${e.message} " )
306+ }
307+ } catch (e: Throwable ) {
308+ promise.reject(e)
309+ }
310+ }
311+ }
312+
278313 @ReactMethod
279314 override fun hash (path : String , algorithm : String , promise : Promise ) {
280315 ioScope.launch {
@@ -455,6 +490,40 @@ class FileAccessModule internal constructor(context: ReactApplicationContext) :
455490 }
456491 }
457492
493+ @ReactMethod
494+ override fun symlink (source : String , target : String , promise : Promise ) {
495+ ioScope.launch {
496+ try {
497+ if (source.isContentUri() || target.isContentUri()) {
498+ promise.reject(" ERR" , " Symbolic links are not supported for content URIs" )
499+ return @launch
500+ }
501+
502+ val sourceFile = parsePathToFile(source)
503+ val targetFile = parsePathToFile(target)
504+
505+ if (! sourceFile.exists()) {
506+ promise.reject(" ENOENT" , " Source file '$source ' does not exist" )
507+ return @launch
508+ }
509+
510+ if (targetFile.exists()) {
511+ promise.reject(" EEXIST" , " Target file '$target ' already exists" )
512+ return @launch
513+ }
514+
515+ try {
516+ Files .createSymbolicLink(targetFile.toPath(), sourceFile.toPath())
517+ promise.resolve(null )
518+ } catch (e: IOException ) {
519+ promise.reject(" ERR" , " Failed to create symbolic link: ${e.message} " )
520+ }
521+ } catch (e: Throwable ) {
522+ promise.reject(e)
523+ }
524+ }
525+ }
526+
458527 @ReactMethod
459528 override fun unlink (path : String , promise : Promise ) {
460529 ioScope.launch {
0 commit comments