CachedLayer writeUncompressed(Blob uncompressedLayerBlob, @Nullable DescriptorDigest selector)
      throws IOException {
    // Creates the layers directory if it doesn't exist.
    Files.createDirectories(cacheStorageFiles.getLayersDirectory());

    // Creates the temporary directory. The temporary directory must be in the same FileStore as the
    // final location for Files.move to work.
    Files.createDirectories(cacheStorageFiles.getTemporaryDirectory());
    try (TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider()) {
      Path temporaryLayerDirectory =
          tempDirectoryProvider.newDirectory(cacheStorageFiles.getTemporaryDirectory());

      // Writes the layer file to the temporary directory.
      WrittenLayer writtenLayer =
          writeUncompressedLayerBlobToDirectory(uncompressedLayerBlob, temporaryLayerDirectory);

      // Moves the temporary directory to the final location.
      moveIfDoesNotExist(
          temporaryLayerDirectory, cacheStorageFiles.getLayerDirectory(writtenLayer.layerDigest));

      // Updates cachedLayer with the blob information.
      Path layerFile =
          cacheStorageFiles.getLayerFile(writtenLayer.layerDigest, writtenLayer.layerDiffId);
      CachedLayer.Builder cachedLayerBuilder =
          CachedLayer.builder()
              .setLayerDigest(writtenLayer.layerDigest)
              .setLayerDiffId(writtenLayer.layerDiffId)
              .setLayerSize(writtenLayer.layerSize)
              .setLayerBlob(Blobs.from(layerFile));

      // Write the selector file.
      if (selector != null) {
        writeSelector(selector, writtenLayer.layerDigest);
      }

      return cachedLayerBuilder.build();
    }
  }
Writes an uncompressed {@link Blob} out to the cache directory.

<p>Cache is written out in the form:

<ul>
  <li>The {@code uncompressedLayerBlob} is written to the layer directory under the layers
      directory corresponding to the layer blob.
  <li>The {@code selector} is written to the selector file under the selectors directory.
</ul>

@param uncompressedLayerBlob the {@link Blob} containing the uncompressed layer contents to
    write out
@param selector the optional selector digest to also reference this layer data. A selector
    digest may be a secondary identifier for a layer that is distinct from the default layer
    digest.
@return the {@link CachedLayer} representing the written entry
@throws IOException if an I/O exception occurs
jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheStorageWriter.java