UXP accessing files and folders

I would love to get some clarification on the FS module. According to the documentation a native “file:” scheme for the path parameter can be used to access and read the file. I’m in a situation where I want to read a file using the FS.readFile path but instead I keet on getting the error "Route not found". what could be the issue or the way out. below is my code

let path = "file:///C:/Users/chelse/united /Pictures/Screenshots/cup.jpg"
const data  = await FS.readFile(path);

Again how do you check for the existence of a file in a folder since FS.existSync doesn’t exist on uxp.

require('uxp').storage.localFileSystem does not allow reading or writing files without user interaction.
namely: fs.getFolder(), fs.getFileForOpening() and fs.getFileForSaving("hello.txt")

read more about getting access to the local file system here

to check the existence of a file, you request acces to it by using getFileForOpening or by using folder.getEntry(filePath)

then you check if is defined / if entry.isFile

you may also want to create a “token” from entry.
a token is a string that can be used in batchPlay and can be persistent or temporary


also check out require(‘fs’)

what is the difference between the above fs and this https://developer.adobe.com/xd/uxp/uxp/reference-js/Modules/FileSystem/

I thought I could access the file using the fs.readFile listed in the above

require(‘fs’) can’t be used for saving and opening files (in the context of PS documents and images) AFAIK. it just reads raw data and does not return an entry file so it can’t be used with functions that expects entries.
it also requires permissions in the manifest.

however I read in the forums that arbitrary file access is planned but I wouldn’t hold my breath

See my thread here for a working example of using fs.readdir().
Worth noting that you also need to grant fullAccess permission for local in your manifest.

how do you grant fullAccess permission for local in manifest. I can’t see that in the documentation

It’s here on the documentation page for Manifest V5.

There may be too many ‘/’ after ‘file:’. Would the following example work?

const FS = require('fs');
let path = "file:C:\\Users\\chelse\\united \\Pictures\\Screenshots\\cup.jpg";
const data  = await FS.readFile(path);

In this example, I have changed the path to a Windows-style path. The only reason is that I am not familiar with how the drive letter (C:) is represented in a POSIX path. In macOS it should look something like this.

const FS = require('fs');
let path = "file:/Users/chelse/united /Pictures/Screenshots/cup.jpg";
const data  = await FS.readFile(path);

Then this solution would be tricky for me since am working on manifest 4

I’ve tried the windows version and it keeps on throwing, "Route not found". None of the above solution works for me. Funny thing is, I’ve copy pasted the link from windows file system itself where it works correctly and pasted it in the editor and tried running it and thus the error. I’ve copy pasted the link as you pasted and pasted it on windows and windows threw an error.

My solution also assumes that you are using manifest v5 and giving fullAccess permission for local. Sorry.

Nope. Am on manifest 4. is it of a neccessity that all plugins relying on manifest 4 shift to manifest 5
?

Thanks guys. with manifest 5 it has worked

1 Like

It didn’t work here! @Adobe256 would you mind showing how the file code turned out. js and the changes I have to make to the manifest file? Thanks

First of all update your UXP to the latest version. Also make sure Photoshop is beyond version 23.0.0 + . Maneuver to this link [https://developer.adobe.com/photoshop/uxp/2022/guides/uxp_guide/uxp-misc/manifest-v5/#local-filesystem](https://localfilesystem permission) and enable the FullAccess permission on your manifest. the above code works well. Make sure the manifest version reads 5+. Actually, try create a sample plugin using the uxp create plugin button and experiment. I’ll share the code in a few when am completely done

Oh sorry I had forgotten. .

on your manifest 5 add this after icons.

 "requiredPermissions": {
        "localFileSystem": "fullAccess", // this is important for the access
      // with regards to the question the rest is not of much importance
        "network": {
            "domains": [
                "https://forums.creativeclouddeveloper.com/t/uxp-accessing-files-and-folders/5930/15",                        
            ]
        }, 
    "launchProcess": {
        "schemes": [
          "http",
          "https"
        ],
        "extensions": [
          ".svg",
          ".png",
          ".pdf",
          ".xd", 
          ".psd"
        ]
      },
       "allowCodeGenerationFromStrings": true        
    }

// code for reading file from disk


 function readFileFromDisk() {
  try {
    // make sure an active doc is opened
    // check if any file is open. if not return error
    let activeDocument = (PS.app.activeDocument as PS.Document) || null
    if (activeDocument === null) {
      return psCore.showAlert({ message: 'Please open a document' })
    }   

    // check if file is saved before proceeding
    if(!activeDocument.save){
      // request the user to save it 
//return an alert
}

    // fetching the file
 
    if (activeDococument.path === undefined) {
    // for some reasons am yet to understand the path is undefined for some files
      return psCore.showAlert('Error fetching file path.')
    }
    
    // read the file
    const fileBuffer: ArrayBuffer = await FS.readFile(`file:${activeDoc.path}`) // 

    // fetch the file's name
    let fileName: string = activeDocument.title

  console.log('filename', fileName,'  file Array Buffer ', fileBuffer) 

    
  } catch (error) {
    console.error(' Error : ', error)
   
  }
}
1 Like

I kept getting this error as well, my problem was I did not have “file:” as a prefix on the fullpath string.

good:
"file:c:\\path\\to\\allowed\\file.json"
bad:
"c:\\path\\to\\allowed\\file.json"

Thats all I got to contribute and it is the total opposite of Zobs opinion:

I am not a professional, but for me it worked.