<!DOCTYPE html><htmllang="en-US"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=Edge"><title>File APIs - SyncFiles Documentation</title><linkrel="shortcut icon"href="/syncfiles/favicon.ico"type="image/x-icon"><linkrel="stylesheet"href="/syncfiles/assets/css/just-the-docs-default.css"><scripttype="text/javascript"src="/syncfiles/assets/js/vendor/lunr.min.js"></script><scripttype="text/javascript"src="/syncfiles/assets/js/just-the-docs.js"></script><metaname="viewport"content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 --><title>File APIs | SyncFiles Documentation</title><metaname="generator"content="Jekyll v4.2.2"/><metaproperty="og:title"content="File APIs"/><metaproperty="og:locale"content="en_US"/><metaname="description"content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."/><metaproperty="og:description"content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."/><linkrel="canonical"href="https://depp.github.io/syncfiles/tech/apis"/><metaproperty="og:url"content="https://depp.github.io/syncfiles/tech/apis"/><metaproperty="og:site_name"content="SyncFiles Documentation"/><metaproperty="og:type"content="website"/><metaname="twitter:card"content="summary"/><metaproperty="twitter:title"content="File APIs"/><scripttype="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","headline":"File APIs","url":"https://depp.github.io/syncfiles/tech/apis"}</script><!-- End Jekyll SEO tag --></head><body><svgxmlns="http://www.w3.org/2000/svg"style="display: none;"><symbolid="svg-link"viewBox="0 0 24 24"><title>Link</title><svgxmlns="http://www.w3.org/2000/svg"width="24"height="24"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"class="feather feather-link"><pathd="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><pathd="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></symbol><symbolid="svg-search"viewBox="0 0 24 24"><title>Search</title><svgxmlns="http://www.w3.org/2000/svg"width="24"height="24"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"class="feather feather-search"><circlecx="11"cy="11"r="8"></circle><linex1="21"y1="21"x2="16.65"y2="16.65"></line></svg></symbol><symbolid="svg-menu"viewBox="0 0 24 24"><title>Menu</title><svgxmlns="http://www.w3.org/2000/svg"width="24"height="24"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"class="feather feather-menu"><linex1="3"y1="12"x2="21"y2="12"></line><linex1="3"y1="6"x2="21"y2="6"></line><linex1="3"y1="18"x2="21"y2="18"></line></svg></symbol><symbolid="svg-arrow-right"viewBox="0 0 24 24"><title>Expand</title><svgxmlns="http://www.w3.org/2000/svg"width="24"height="24"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"class="feather feather-chevron-right"><polylinepoints="9 18 15 12 9 6"></polyline></svg></symbol><symbolid="svg-doc"viewBox="0 0 24 24"><title>Document</title><svgxmlns="http://www.w3.org/2000/svg"width="24"height="24"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"class="feather feather-file"><pathd="M132H6a22000-22v16a2200022h12a220
</code></pre></div></div><p>This is equivalent to:</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="k">const</span><spanclass="kt">unsigned</span><spanclass="kt">char</span><spanclass="n">kFilename</span><spanclass="p">[</span><spanclass="mi">8</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="p">{</span>
</code></pre></div></div><p>Pascal strings are encoded using one of the old Macintosh character encodings, such as Mac OS Roman. In some cases, the encoding is assumed to be the system’s encoding, whatever that is. In other cases, the encoding is explicitly specified using a <codeclass="language-plaintext highlighter-rouge">ScriptCode</code> (although this value is somewhat ambiguous). In other cases still, the actual encoding is ignored and the string is treated as if it were encoded using the Mac OS Roman encoding.</p><h2id="early-mac-os"><ahref="#early-mac-os"class="anchor-heading"aria-labelledby="early-mac-os"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Early Mac OS </h2><p>The filesystem on the very first Macintosh, later called the Mac 128K, did not support folders or directories. Each file was identified by volume ID and name. For example, <codeclass="language-plaintext highlighter-rouge">OpenDF</code> opens the data fork of a file (presumably, <codeclass="language-plaintext highlighter-rouge">DF</code> stands for “data fork”—there is a corresponding <codeclass="language-plaintext highlighter-rouge">OpenRF</code> for the resource fork), and <codeclass="language-plaintext highlighter-rouge">Create</code> creates a new file.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="n">OSErr</span><spanclass="nf">OpenDF</span><spanclass="p">(</span>
</code></pre></div></div><p>Filenames have a maximum length of 63 characters and are case insensitive. Systems from this era did not support multiple character encodings, so the encoding did not need to be specified. Note that the 63-character limit is an API limit, and common filesystems have a lower, 31-character limit.</p><p>You should not be using this API unless you are targeting <em>extremely</em> old Macintosh systems, like the Mac 128K. This API became obsolete with the introduction of 128K ROMs with the Mac Plus in 1986.</p><p>This API is not part of Carbon and cannot be used on Mac OS X.</p><h3id="swapping-floppy-disks"><ahref="#swapping-floppy-disks"class="anchor-heading"aria-labelledby="swapping-floppy-disks"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Swapping Floppy Disks </h3><p>During this era, it was common to swap floppy disks while a program was running. You can run a program from one disk and save files on another disk. When a program tries to access a file that’s on a different disk, the operating system ejects the current disk and prompts the user to insert the correct disk. This happens automatically; programs do not need to include any code to make this possible.</p><h3id="compatibility-with-hfs"><ahref="#compatibility-with-hfs"class="anchor-heading"aria-labelledby="compatibility-with-hfs"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Compatibility with HFS </h3><p>Old applications written to use this API continue to work after files after the introduction of the hierarchical filesystem. The way this happens is through something called <em>working directories</em>.</p><p>A working directory is the combination of a volume ID and a directory ID, and it can be used in place of a volume ID in the filesystem API. The intent is that old code which only uses volume IDs can be used to save files in different locations on the filesystem. For example, if an old application creates a “save file” dialog box, instead of a volume ID, the dialog box returns a working directory pointing to the directory where the user chose to save the file.</p><h2id="hierarchical-api"><ahref="#hierarchical-api"class="anchor-heading"aria-labelledby="hierarchical-api"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Hierarchical API </h2><p>Alongside Apple’s first hard disk for the Macintosh, the operating system introduced a new filesystem (HFS) which supported directories, and this required a new API. Instead of <codeclass="language-plaintext highlighter-rouge">OpenDF</code>, programs now call <codeclass="language-plaintext highlighter-rouge">HOpenDF</code> to the data fork of a file, and call <codeclass="language-plaintext highlighter-rouge">HCreate</code> instead of <codeclass="language-plaintext highlighter-rouge">Create</code>. Presumably, “H” stands for “hierarchical”.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="n">OSErr</span><spanclass="nf">HOpenDF</span><spanclass="p">(</span>
</code></pre></div></div><p>In this API, files are identified by volume ID, the directory ID within that volume, and the filename within that directory. The encoding is not specified, and presumably, files will be created using the system’s default character encoding.</p><h2id="fsspec-api"><ahref="#fsspec-api"class="anchor-heading"aria-labelledby="fsspec-api"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> FSSpec API </h2><p>The FSSpec API does not change semantics, but provides a simple data structure which is used to store the volume ID, directory ID, and filename. This structure is called <codeclass="language-plaintext highlighter-rouge">FSSpec</code>.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="k">struct</span><spanclass="n">FSSpec</span><spanclass="p">{</span>
</code></pre></div></div><p>Functions which use an <codeclass="language-plaintext highlighter-rouge">FSSpec</code> are named with the <codeclass="language-plaintext highlighter-rouge">FSp</code> prefix. These functions are preferred for over the previous versions for their simplicity. For example, <codeclass="language-plaintext highlighter-rouge">FSpOpenDF</code>, which opens a file’s data fork, and <codeclass="language-plaintext highlighter-rouge">FSpCreate</code>, which creates a new file:</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="n">OSErr</span><spanclass="nf">FSpOpenDF</span><spanclass="p">(</span>
</code></pre></div></div><p>Note that the character encoding is specified when creating a file, using the <codeclass="language-plaintext highlighter-rouge">scriptTag</code> parameter (although technically, this does not completely specify an encoding). The character encoding is not specified when opening a file, instead, the encoding is ignored and treated as if it were the Mac OS Roman encoding.</p><p>This API <em>preserves</em> the encoding used for filenames, but you only need the correct bytestring to refer to existing files.</p><p>Starting in Mac OS X 10.4, this API and other APIs before it are marked as deprecated.</p><h2id="fsref-api"><ahref="#fsref-api"class="anchor-heading"aria-labelledby="fsref-api"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> FSRef API </h2><p>Mac OS 9 introduces a new opaque alternative to <codeclass="language-plaintext highlighter-rouge">FSSpec</code> called <codeclass="language-plaintext highlighter-rouge">FSRef</code>. You can use an <codeclass="language-plaintext highlighter-rouge">FSRef</code> to refer to an existing file, but there is no way to get any information from an <codeclass="language-plaintext highlighter-rouge">FSRef</code> without invoking the filesystem API. The <codeclass="language-plaintext highlighter-rouge">FSRef</code> is not a drop-in replacement for <codeclass="language-plaintext highlighter-rouge">FSSpec</code>, beceause a <codeclass="language-plaintext highlighter-rouge">FSRef</code> must refer to an existing file, and therefore, cannot be used to create a new file.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="k">struct</span><spanclass="n">FSRef</span><spanclass="p">{</span>
</code></pre></div></div><p>The <codeclass="language-plaintext highlighter-rouge">FSRef</code> structure is private to an application and cannot be assumed to be valid if the file is moved/renamed, if the volume is unmounted and remounted, or if the structure is passed to another process. We can speculate that the <codeclass="language-plaintext highlighter-rouge">FSRef</code> structure contains information about a file like its filesystem inode, which can be used to look up the file name.</p><p>You can convert an <codeclass="language-plaintext highlighter-rouge">FSSpec</code> to an <codeclass="language-plaintext highlighter-rouge">FSRef</code>, although this will fail if the file does not exist:</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="n">OSErr</span><spanclass="nf">FSpMakeFSRef</span><spanclass="p">(</span>
</code></pre></div></div><p>The <codeclass="language-plaintext highlighter-rouge">FSRef</code> API has some other differences. For example, when you open a file, you specify the name of the fork you want to open. Previous APIs used different functions for opening the data fork and the resource fork. File names are now specified as Unicode strings encoded with UTF-16.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="n">OSErr</span><spanclass="nf">FSOpenFork</span><spanclass="p">(</span>
</code></pre></div></div><p>This API is a part of Carbon. Carbon was never ported to 64-bit architectures, and was deprecated in Mac OS X 10.8. The last version that supports this API is macOS 10.14, which is the last version of macOS that supports 32-bit programs.</p><h2id="unix-api"><ahref="#unix-api"class="anchor-heading"aria-labelledby="unix-api"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Unix API </h2><p>Mac OS X brought us the Unix APIs:</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kt">int</span><spanclass="nf">open</span><spanclass="p">(</span>
</code></pre></div></div><p>The <codeclass="language-plaintext highlighter-rouge">openat</code> call is available from Mac OS 10.10 onwards.</p><p>Strings are now null-terminated C strings, which are interpreted as UTF-8. Mac OS filesystems do not support arbitrary bytestrings as filenames. If you try to create a file with <codeclass="language-plaintext highlighter-rouge">open</code> with a filename that is not supported by the filesystem, the system call will fail and set <codeclass="language-plaintext highlighter-rouge">errno</code> to <codeclass="language-plaintext highlighter-rouge">EILSEQ</code> (92). This is not documented in the man page for <codeclass="language-plaintext highlighter-rouge">open</code>.</p><h3id="forks-on-unix"><ahref="#forks-on-unix"class="anchor-heading"aria-labelledby="forks-on-unix"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Forks on Unix </h3><p>The resource fork can be accessed as if it were a separate file. To access the resource fork, append <codeclass="language-plaintext highlighter-rouge">/rsrc</code> or <codeclass="language-plaintext highlighter-rouge">/..namedfork/rsrc</code> to the file path. This allows you to view resource fork data through ordinary Unix APIs or with Unix command-line utilities like <codeclass="language-plaintext highlighter-rouge">hexdump</code> and <codeclass="language-plaintext highlighter-rouge">ls</code>.</p><p>Linux also allows you to access the resource fork by appending <codeclass="language-plaintext highlighter-rouge">/rsrc</code> to the file path, for filesystems that support resource forks.</p><h3id="extended-attributes"><ahref="#extended-attributes"class="anchor-heading"aria-labelledby="extended-attributes"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Extended Attributes </h3><p>Starting in version 10.4, Mac OS X provides an interface for accessing extended attributes on a file.</p><divclass="language-c highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kt">ssize_t</span><spanclass="nf">getxattr</span><spanclass="p">(</span>
</code></pre></div></div><p>The resource fork is presented as an extended attribute with the name <codeclass="language-plaintext highlighter-rouge">com.apple.ResourceFork</code>. Since resource forks can be as much as 16 MiB in size, the <codeclass="language-plaintext highlighter-rouge">getxattr</code> function provides a way to read portions of the resource fork without having to read the entire fork.</p><p>Finder info is contained in an attribute named <codeclass="language-plaintext highlighter-rouge">com.apple.FinderInfo</code>.</p><h2id="aliases-and-bookmarks"><ahref="#aliases-and-bookmarks"class="anchor-heading"aria-labelledby="aliases-and-bookmarks"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Aliases and Bookmarks </h2><p>Mac OS also provides facilities to store a reference to a file. These references are designed to be durable, and work even if the file is moved and renamed. These references work by containing various pieces of metadata about the file. If the file is moved, the metadata can be used to find it again.</p><p>On older Mac OS systems, these records are called <em>aliases</em> and you can create them using the alias manager APIs, which are available starting in System 7.</p><p>In Cocoa, these records are called <em>bookmarks</em>.</p><p>The main use of aliases and bookmarks is to store references to files in the “recently used files” menu option in applications.</p></div></div><divclass="search-overlay"></div></div></body></html>