Skip to content

File System API Migration

ScanuNicco edited this page Sep 25, 2021 · 31 revisions

Significant API changes were made in Sprint 34 as part of the [File System Evolution](File System) plan:

Note: These quick reference tables don't cover arguments or return values in detail. Be sure to check the detailed JSDoc comments on the new APIs for full usage details -- see FileSystem.js, File.js, Directory.js, & base class FileSystemEntry.js.

  • For example, the old APIs used two separate success & error callbacks, while the new APIs use a single callback with combined arguments.

Backwards-compatible APIs

These APIs are either unchanged or "drop-in compatible" - code using them probably does not need to change at all, though in some unusual usage scenarios the APIs may behave differently from before.

Old API New API Notes Usage
FileEntry
DirectoryEntry
File
Directory
Drop-in compatible (same fields/members) (lots)
entry.fullPath, entry.isFile, entry.isDirectory (unchanged) Properties are now read-only fullPath: many
isFile/Directory: 9
FileUtils.readAsText(fileEntry) (same except takes new objects) Drop-in compatible 13
FileUtils.writeText(fileEntry) (same except takes new objects) Drop-in compatible 5
Concatenation: folderPath + "/" + filename (unchanged) Doubled "/"es are now normalized out by fs APIs
Concatenation: folderPath + filename (unchanged) Directory.fullPath always ends in "/", just like DirectoryEntry.fullPath Several
Substrings: relpath = fullPath.slice(dirFullPath.length) (unchanged) Directory.fullPath always ends in "/", just like DirectoryEntry.fullPath

Removed APIs

These APIs are completely gone - code using them will throw exceptions. Extensions using these APIs will be broken immediately, and should be fixed ASAP.

Old API New API Notes Usage
fileEntry.file()... new NativeFileSystem.FileReader().readAsText(fileObj) file.read() None
DirectoryEntry.getFile(relpath, {create:true}) filesystem.getFileForPath(fullPath).write("") 2
DirectoryEntry.getDirectory(relpath, {create:true}) filesystem.getDirectoryForPath(fullPath).create() 2
ProjectManager "projectFilesChange" event FileSystem "change" event 2
fileEntry.getMetadata() file.stat()
(note: fields of resulting object differ also)
1
NativeFileError.* FileSystemError.*
(different constants)
1
error.name
e.g. when passing to FileUtils.showFileOpenError()
error
(errors are now string constants)
2
instanceof NativeFileSystem.InaccessibleFileEntry instanceof InMemoryFile 1
entry.remove() entry.moveToTrash() None
entry.filesystem n/a None
NativeFileSystem.Encodings.* (none) None
NativeFileSystem.isRelativePath() !FileSystem.isAbsolutePath() None
FileUtils.isAffectedWhenRenaming() n/a None
FileUtils.updateFileEntryPath() n/a None
FileUtils.getFilenameExtension()
(this was already deprecated)
FileUtils.getFileExtension()
(note: different return value)
None

Deprecated APIs

These APIs will temporarily continue to behave as before, but will be removed in the near future. Extensions using these APIs should be fixed relatively soon, within the next sprint or two.

Under the hood, the old API has been reimplemented in terns of the new APIs, so there may be subtle differences noticeable in some edge use cases. (Also - the shim code may be a helpful reference when migrating over to the new APIs).

Old API New API Notes Usage
new NativeFileSystem.FileEntry(fullPath)
new NativeFileSystem.DirectoryEntry(fullPath)
filesystem.getFileForPath(fullPath)
filesystem.getDirectoryForPath(fullPath)
(You never directly construct a File / Directory)
These now return a File / Directory object using the new APIs instead of constructing a FileEntry / DirectoryEntry 19
DirectoryEntry.getFile(relpath)
DirectoryEntry.getDirectory(relpath)
(*without* 'create' flag)
filesystem.resolve(dirFullPath + relpath) 4
NativeFileSystem.resolveNativeFileSystemPath(fullPath) filesystem.resolve(path) 4
NativeFileSystem.requestNativeFileSystem(fullPath)... fs.root filesystem.resolve(fullPath) 6
directoryEntry.createReader().readEntries() directory.getContents() 5
fileEntry.createWriter()... writer.write(text) file.write(text) 5 (unused in 3)
NativeFileSystem.showOpenDialog()
NativeFileSystem.showSaveDialog()
filesystem.showOpenDialog()
filesystem.showSaveDialog()
4
FileIndexManager.getFileInfoList("all")
FileIndexManager.getFileInfoList("css")
ProjectManager.getAllFiles()
ProjectManager.getAllFiles(
   ProjectManager.getLanguageFilter("css") )
Returns an array of Files, but they provide same properties as the old FileInfos 7
FileIndexManager.getFilenameMatches("...", filename) ProjectManager.getAllFiles(filter) None
brackets.fs.*() (various) These low-level APIs continue to exist, but have never been officially supported. They may break at any time. Several

Extensions that will break

The following 9 extensions use at least one API on the "Removed" list:

  • angularui.angularjs -- (FileEntry.getMetadata())
  • bsirlinger.github-access -- (DirectoryEntry.getFile({create}), DirectoryEntry.getDirectory({create}))
  • xunit -- (DirectoryEntry.getFile({create}), DirectoryEntry.getDirectory({create})
  • zaggino.brackets-git (won't crash, but notable bug) -- ("projectFilesChange" event)
  • variousimprovements (won't crash, minor bug) -- ("projectFilesChange" event)
  • camden.caniuse (won't crash, minor bug) -- (FileError.name)
  • jrowny.brackets.snippets (won't crash, minor bug) -- (FileError.name, though was buggy already)
  • pflynn.brackets.editor.nav (won't crash, very minor bug) -- (InaccessibleFileEntry)
  • interactive-linter (no effect on behavior) -- (NativeFileError)

We will file bugs with all extensions that are using removed APIs to make sure authors are aware of the change.

Clone this wiki locally