diff --git a/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj b/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj
new file mode 100644
index 0000000..e36621b
--- /dev/null
+++ b/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj
@@ -0,0 +1,27 @@
+
+
+
+ SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+
+
+
+ SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+ SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+ SharpGrip FileSystem Google Cloud Storage adapter
+ The SharpGrip FileSystem Google Cloud Storage adapter.
+ sharpgrip;file-system;google-cloud-storage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs
new file mode 100644
index 0000000..f8f2d62
--- /dev/null
+++ b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs
@@ -0,0 +1,321 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using Google;
+using Google.Cloud.Storage.V1;
+using SharpGrip.FileSystem.Exceptions;
+using SharpGrip.FileSystem.Extensions;
+using SharpGrip.FileSystem.Models;
+using SharpGrip.FileSystem.Utilities;
+using DirectoryNotFoundException = SharpGrip.FileSystem.Exceptions.DirectoryNotFoundException;
+using FileNotFoundException = SharpGrip.FileSystem.Exceptions.FileNotFoundException;
+using Object = Google.Apis.Storage.v1.Data.Object;
+
+namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+{
+ public class GoogleCloudStorageAdapter : Adapter
+ {
+ private readonly StorageClient client;
+ private readonly string bucketName;
+
+ public GoogleCloudStorageAdapter(string prefix, string rootPath, StorageClient client, string bucketName, Action? configuration = null)
+ : base(prefix, rootPath, configuration)
+ {
+ this.client = client;
+ this.bucketName = bucketName;
+ }
+
+ public override void Dispose()
+ {
+ client.Dispose();
+ }
+
+ public override async Task ConnectAsync(CancellationToken cancellationToken = default)
+ {
+ Logger.LogStartConnectingAdapter(this);
+ await Task.CompletedTask;
+ Logger.LogFinishedConnectingAdapter(this);
+ }
+
+ public override async Task GetFileAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash();
+
+ try
+ {
+ var file = await client.GetObjectAsync(bucketName, path, new GetObjectOptions(), cancellationToken);
+
+ if (file == null)
+ {
+ throw new FileNotFoundException(path, Prefix);
+ }
+
+ return ModelFactory.CreateFile(file, path, virtualPath);
+ }
+ catch (GoogleApiException googleApiException) when (googleApiException.HttpStatusCode == HttpStatusCode.NotFound)
+ {
+ throw new FileNotFoundException(path, Prefix);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task GetDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash();
+ var parentPath = GetParentPathPart(path).EnsureTrailingForwardSlash();
+
+ try
+ {
+ if (path.IsNullOrEmpty() || path == "/")
+ {
+ return ModelFactory.CreateDirectory("/", path, virtualPath);
+ }
+
+ var request = client.Service.Objects.List(bucketName);
+
+ request.Prefix = parentPath == "/" ? null : parentPath;
+ request.Delimiter = "/";
+
+ do
+ {
+ var objects = await request.ExecuteAsync(cancellationToken: cancellationToken);
+
+ if (objects.Prefixes != null)
+ {
+ foreach (var directoryPath in objects.Prefixes)
+ {
+ if (directoryPath == path)
+ {
+ var directoryName = GetLastPathPart(directoryPath);
+
+ return ModelFactory.CreateDirectory(directoryName.RemoveTrailingForwardSlash(), directoryPath.EnsureTrailingForwardSlash(), GetVirtualPath(directoryPath));
+ }
+ }
+ }
+
+ request.PageToken = objects.NextPageToken;
+ } while (request.PageToken != null);
+
+ throw new DirectoryNotFoundException(path, Prefix);
+ }
+ catch (GoogleApiException googleApiException) when (googleApiException.HttpStatusCode == HttpStatusCode.NotFound)
+ {
+ throw new DirectoryNotFoundException(path, Prefix);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task> GetFilesAsync(string virtualPath = "", CancellationToken cancellationToken = default)
+ {
+ await GetDirectoryAsync(virtualPath, cancellationToken);
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash();
+
+ try
+ {
+ var files = new List();
+
+ var request = client.Service.Objects.List(bucketName);
+
+ request.Prefix = path == "/" ? null : path;
+ request.Delimiter = "/";
+
+ do
+ {
+ var objects = await request.ExecuteAsync(cancellationToken: cancellationToken);
+
+ if (objects.Items != null)
+ {
+ foreach (var file in objects.Items.Where(item => item.ContentType != null))
+ {
+ files.Add(ModelFactory.CreateFile(file, file.Name.RemoveTrailingForwardSlash(), GetVirtualPath(file.Name)));
+ }
+ }
+
+ request.PageToken = objects.NextPageToken;
+ } while (request.PageToken != null);
+
+ return files;
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task> GetDirectoriesAsync(string virtualPath = "", CancellationToken cancellationToken = default)
+ {
+ await GetDirectoryAsync(virtualPath, cancellationToken);
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash();
+
+ try
+ {
+ var directories = new List();
+
+ var request = client.Service.Objects.List(bucketName);
+
+ request.Prefix = path == "/" ? null : path;
+ request.Delimiter = "/";
+
+ do
+ {
+ var objects = await request.ExecuteAsync(cancellationToken: cancellationToken);
+
+ if (objects.Prefixes != null)
+ {
+ foreach (var directoryPath in objects.Prefixes)
+ {
+ var directoryName = GetLastPathPart(directoryPath);
+
+ directories.Add(ModelFactory.CreateDirectory(directoryName.RemoveTrailingForwardSlash(), directoryPath.EnsureTrailingForwardSlash(), GetVirtualPath(directoryPath)));
+ }
+ }
+
+ request.PageToken = objects.NextPageToken;
+ } while (request.PageToken != null);
+
+ return directories;
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task CreateDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ if (await DirectoryExistsAsync(virtualPath, cancellationToken))
+ {
+ throw new DirectoryExistsException(GetPath(virtualPath), Prefix);
+ }
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash();
+
+ try
+ {
+ await client.UploadObjectAsync(bucketName, path.EnsureTrailingForwardSlash(), null, Stream.Null, cancellationToken: cancellationToken);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task DeleteDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ await GetDirectoryAsync(virtualPath, cancellationToken);
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash();
+
+ try
+ {
+ var files = await GetFilesAsync(virtualPath, cancellationToken);
+
+ foreach (var file in files)
+ {
+ await DeleteFileAsync(file.VirtualPath, cancellationToken);
+ }
+
+ var subDirectories = await GetDirectoriesAsync(virtualPath, cancellationToken);
+
+ foreach (var subDirectory in subDirectories)
+ {
+ await DeleteDirectoryAsync(subDirectory.VirtualPath, cancellationToken);
+ }
+
+ await client.DeleteObjectAsync(bucketName, path, cancellationToken: cancellationToken);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task DeleteFileAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ await GetFileAsync(virtualPath, cancellationToken);
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash();
+
+ try
+ {
+ await client.DeleteObjectAsync(bucketName, path, cancellationToken: cancellationToken);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task ReadFileStreamAsync(string virtualPath, CancellationToken cancellationToken = default)
+ {
+ await GetFileAsync(virtualPath, cancellationToken);
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash();
+
+ try
+ {
+ var file = await client.GetObjectAsync(bucketName, path, new GetObjectOptions(), cancellationToken);
+
+ var memoryStream = new MemoryStream();
+
+ await client.DownloadObjectAsync(file, memoryStream, new DownloadObjectOptions(), cancellationToken);
+
+ memoryStream.Position = 0;
+
+ return memoryStream;
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ public override async Task WriteFileAsync(string virtualPath, Stream contents, bool overwrite = false, CancellationToken cancellationToken = default)
+ {
+ if (!overwrite && await FileExistsAsync(virtualPath, cancellationToken))
+ {
+ throw new FileExistsException(GetPath(virtualPath), Prefix);
+ }
+
+ var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash();
+
+ try
+ {
+ var file = new Object
+ {
+ Bucket = bucketName,
+ Name = path,
+ ContentType = ContentTypeProvider.GetContentType(path)
+ };
+
+ await client.UploadObjectAsync(file, contents, new UploadObjectOptions(), cancellationToken);
+ }
+ catch (Exception exception)
+ {
+ throw Exception(exception);
+ }
+ }
+
+ protected override Exception Exception(Exception exception)
+ {
+ if (exception is FileSystemException)
+ {
+ return exception;
+ }
+
+ return new AdapterRuntimeException(exception);
+ }
+ }
+}
\ No newline at end of file
diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs
new file mode 100644
index 0000000..dc83161
--- /dev/null
+++ b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs
@@ -0,0 +1,8 @@
+using SharpGrip.FileSystem.Configuration;
+
+namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+{
+ public class GoogleCloudStorageAdapterConfiguration : AdapterConfiguration
+ {
+ }
+}
\ No newline at end of file
diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs b/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs
new file mode 100644
index 0000000..6a49dab
--- /dev/null
+++ b/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs
@@ -0,0 +1,44 @@
+using Google.Apis.Storage.v1.Data;
+using SharpGrip.FileSystem.Models;
+using SharpGrip.FileSystem.Utilities;
+
+namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage
+{
+ public static class ModelFactory
+ {
+ public static FileModel CreateFile(Object file, string path, string virtualPath)
+ {
+ return new FileModel
+ {
+ Name = PathUtilities.GetLastPathPart(file.Name),
+ Path = path,
+ VirtualPath = virtualPath,
+ Length = (long?) file.Size,
+ LastModifiedDateTime = file.UpdatedDateTimeOffset?.DateTime,
+ CreatedDateTime = file.TimeCreatedDateTimeOffset?.DateTime
+ };
+ }
+
+ public static DirectoryModel CreateDirectory(string name, string path, string virtualPath)
+ {
+ return new DirectoryModel
+ {
+ Name = name,
+ Path = path,
+ VirtualPath = virtualPath
+ };
+ }
+
+ public static DirectoryModel CreateDirectory(Object directory, string path, string virtualPath)
+ {
+ return new DirectoryModel
+ {
+ Name = directory.Name,
+ Path = path,
+ VirtualPath = virtualPath,
+ LastModifiedDateTime = directory.UpdatedDateTimeOffset?.DateTime,
+ CreatedDateTime = directory.TimeCreatedDateTimeOffset?.DateTime
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/FileSystem.sln b/FileSystem.sln
index 46362fa..b34ff32 100644
--- a/FileSystem.sln
+++ b/FileSystem.sln
@@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.Dropbox
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.Ftp", "FileSystem.Adapters.Ftp\FileSystem.Adapters.Ftp.csproj", "{ED38402A-3667-4701-A974-4D7710E1544A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.GoogleCloudStorage", "FileSystem.Adapters.GoogleCloudStorage\FileSystem.Adapters.GoogleCloudStorage.csproj", "{0E6E0F36-55C4-49FF-9298-99D5B3309381}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.GoogleDrive", "FileSystem.Adapters.GoogleDrive\FileSystem.Adapters.GoogleDrive.csproj", "{CB1F411C-3FB5-4441-9541-423951C17BAF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.MicrosoftOneDrive", "FileSystem.Adapters.MicrosoftOneDrive\FileSystem.Adapters.MicrosoftOneDrive.csproj", "{9955422E-4A50-43CD-BC2B-91E6820F206C}"
@@ -50,6 +52,10 @@ Global
{ED38402A-3667-4701-A974-4D7710E1544A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED38402A-3667-4701-A974-4D7710E1544A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED38402A-3667-4701-A974-4D7710E1544A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Release|Any CPU.Build.0 = Release|Any CPU
{CB1F411C-3FB5-4441-9541-423951C17BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB1F411C-3FB5-4441-9541-423951C17BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB1F411C-3FB5-4441-9541-423951C17BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/FileSystem/FileSystem.csproj b/FileSystem/FileSystem.csproj
index 2285baa..0bd12ae 100644
--- a/FileSystem/FileSystem.csproj
+++ b/FileSystem/FileSystem.csproj
@@ -9,7 +9,7 @@
SharpGrip.FileSystem
SharpGrip FileSystem
SharpGrip FileSystem is a file system abstraction supporting multiple adapters.
- sharpgrip;file-system;amazon-s3;azure-blob-storage;azure-file-storage;dropbox;ftp;google-drive;microsoft-onedrive;sftp
+ sharpgrip;file-system;amazon-s3;azure-blob-storage;azure-file-storage;dropbox;ftp;google-cloud-storage;google-drive;microsoft-onedrive;sftp
diff --git a/FileSystem/src/Adapters/Adapter.cs b/FileSystem/src/Adapters/Adapter.cs
index a977c21..265445f 100644
--- a/FileSystem/src/Adapters/Adapter.cs
+++ b/FileSystem/src/Adapters/Adapter.cs
@@ -129,9 +129,9 @@ public virtual async Task AppendFileAsync(string virtualPath, Stream contents, C
public abstract Task WriteFileAsync(string virtualPath, Stream contents, bool overwrite = false, CancellationToken cancellationToken = default);
protected abstract Exception Exception(Exception exception);
- protected string GetPath(string path)
+ protected string GetPath(string virtualPath)
{
- return PathUtilities.GetPath(path, RootPath);
+ return PathUtilities.GetPath(virtualPath, RootPath);
}
protected string GetVirtualPath(string path)
diff --git a/README.md b/README.md
index aeb6ee4..656a5d2 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,10 @@
## Introduction
-SharpGrip FileSystem is a .NET file system abstraction supporting multiple adapters.
+SharpGrip FileSystem is a versatile .NET file system abstraction that supports multiple storage adapters.
+It empowers developers to manage various file systems and services through a unified and easily comprehensible API.
+By coding against the abstractions provided by this library, developers can sidestep vendor-specific APIs, effectively avoiding vendor lock-ins.
+This flexibility enhances the portability and maintainability of the codebase, allowing for smoother transitions between different file systems.
## Installation
@@ -22,17 +25,18 @@ For adapters other than the local file system (included in the `SharpGrip.FileSy
## Supported adapters
-| Adapter | Package | NuGet |
-|:------------------------------------------------|:--------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [Local adapter](#local-adapter) | `SharpGrip.FileSystem` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) |
-| [AmazonS3](#amazons3-adapter) | `SharpGrip.FileSystem.Adapters.AmazonS3` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) |
-| [AzureBlobStorage](#azureblobstorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureBlobStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) |
-| [AzureFileStorage](#azurefilestorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureFileStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) |
-| [Dropbox](#dropbox-adapter) | `SharpGrip.FileSystem.Adapters.Dropbox` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) |
-| [FTP](#ftp-adapter) | `SharpGrip.FileSystem.Adapters.Ftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) |
-| [GoogleDrive](#googledrive-adapter) | `SharpGrip.FileSystem.Adapters.GoogleDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) |
-| [MicrosoftOneDrive](#microsoftonedrive-adapter) | `SharpGrip.FileSystem.Adapters.MicrosoftOneDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) |
-| [SFTP](#sftp-adapter) | `SharpGrip.FileSystem.Adapters.Sftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) |
+| Adapter | Package | NuGet |
+|:--------------------------------------------------|:---------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [Local adapter](#local-adapter) | `SharpGrip.FileSystem` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) |
+| [AmazonS3](#amazons3-adapter) | `SharpGrip.FileSystem.Adapters.AmazonS3` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) |
+| [AzureBlobStorage](#azureblobstorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureBlobStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) |
+| [AzureFileStorage](#azurefilestorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureFileStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) |
+| [Dropbox](#dropbox-adapter) | `SharpGrip.FileSystem.Adapters.Dropbox` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) |
+| [FTP](#ftp-adapter) | `SharpGrip.FileSystem.Adapters.Ftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) |
+| [GoogleCloudStorage](#googlecloudstorage-adapter) | `SharpGrip.FileSystem.Adapters.GoogleCloudStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleCloudStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleCloudStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.GoogleCloudStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleCloudStorage) |
+| [GoogleDrive](#googledrive-adapter) | `SharpGrip.FileSystem.Adapters.GoogleDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) |
+| [MicrosoftOneDrive](#microsoftonedrive-adapter) | `SharpGrip.FileSystem.Adapters.MicrosoftOneDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) |
+| [SFTP](#sftp-adapter) | `SharpGrip.FileSystem.Adapters.Sftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) |
## Supported operations
@@ -144,6 +148,22 @@ var adapters = new List
var fileSystem = new FileSystem(adapters);
```
+### GoogleCloudStorage adapter
+
+```
+// Google connection.
+var credential = GoogleCredential.FromFile("path/to/credential/file");
+var storageClient = await StorageClient.CreateAsync(credential);
+
+var adapters = new List
+{
+ new LocalAdapter("local", "/var/files"),
+ new GoogleCloudStorageAdapter(prefix, rootPath, storageClient, "bucketName", configuration);
+};
+
+var fileSystem = new FileSystem(adapters);
+```
+
### GoogleDrive adapter
```