Lưu trữ dữ liệu dành riêng cho ứng dụng

Thư mục dữ liệu ứng dụng là một thư mục ẩn đặc biệt mà ứng dụng có thể dùng để lưu trữ dữ liệu dành riêng cho ứng dụng, chẳng hạn như tệp cấu hình. Thư mục dữ liệu ứng dụng sẽ được tạo tự động khi bạn cố gắng tạo một tệp trong đó. Hãy dùng thư mục này để lưu trữ mọi tệp mà người dùng không nên trực tiếp tương tác. Chỉ ứng dụng của bạn mới có thể truy cập vào thư mục này và nội dung của thư mục này sẽ bị ẩn đối với người dùng và các ứng dụng khác của Google Drive.

Thư mục dữ liệu ứng dụng sẽ bị xoá khi người dùng gỡ cài đặt ứng dụng của bạn khỏi phần Drive của tôi. Người dùng cũng có thể xoá thư mục dữ liệu của ứng dụng theo cách thủ công.

Phạm vi thư mục dữ liệu ứng dụng

Trước khi có thể truy cập vào thư mục dữ liệu ứng dụng, bạn phải yêu cầu quyền truy cập vào phạm vi không nhạy cảm https://www.googleapis.com/auth/drive.appdata. Để biết thêm thông tin về các phạm vi và cách yêu cầu quyền truy cập vào các phạm vi đó, hãy tham khảo bài viết Chọn phạm vi API Google Drive. Để biết thêm thông tin về các phạm vi OAuth 2.0 cụ thể, hãy xem bài viết Phạm vi OAuth 2.0 cho các API của Google.

Điểm khác biệt giữa thư mục dữ liệu ứng dụng và thư mục sao lưu Drive

Thư mục dữ liệu ứng dụng tách biệt với thư mục sao lưu Drive.

Thư mục dữ liệu ứng dụng là một thư mục cấu hình được tạo cho mỗi ứng dụng bên thứ ba và mỗi ứng dụng bên thứ ba có thể lưu trữ dữ liệu trong đó. Chỉ ứng dụng đã tạo dữ liệu trong appDataFolder mới có thể truy cập vào dữ liệu đó. Bạn không thể truy cập vào thư mục này bằng giao diện người dùng (UI) của Drive.

Thư mục sao lưu Drive là một thư mục dành riêng mà Drive ghi các bản sao lưu thiết bị vào và thư mục này hiển thị trong giao diện người dùng Drive.

Các quy tắc ràng buộc đối với thư mục dữ liệu ứng dụng

Các quy tắc ràng buộc sau đây được thực thi khi bạn làm việc với thư mục dữ liệu ứng dụng:

  • Bạn không thể chia sẻ tệp hoặc thư mục bên trong thư mục dữ liệu ứng dụng. Nếu bạn cố gắng thực hiện thao tác này, lỗi notSupportedForAppDataFolderFiles sẽ được tạo kèm theo thông báo lỗi sau: "Method not supported for files within the Application Data folder." (Phương thức không được hỗ trợ cho các tệp trong thư mục Dữ liệu ứng dụng).

  • Bạn không thể di chuyển tệp trong appDataFolder giữa các vị trí lưu trữ (không gian). Nếu bạn cố gắng thực hiện thao tác này, lỗi notSupportedForAppDataFolderFiles sẽ được tạo kèm theo thông báo lỗi sau: "Method not supported for files within the Application Data folder." (Phương thức không được hỗ trợ cho các tệp trong thư mục Dữ liệu ứng dụng). Để biết thêm thông tin, hãy xem Tổ chức tệp.

  • Bạn không thể chuyển tệp hoặc thư mục bên trong thư mục dữ liệu ứng dụng vào thùng rác. Nếu bạn cố gắng thực hiện thao tác này, lỗi notSupportedForAppDataFolderFiles sẽ được tạo kèm theo thông báo lỗi sau: "Files within the Application Data folder cannot be trashed." (Không thể chuyển các tệp trong thư mục Dữ liệu ứng dụng vào thùng rác).

Tạo tệp trong thư mục dữ liệu ứng dụng

Để tạo một tệp trong thư mục dữ liệu ứng dụng, hãy chỉ định appDataFolder trong thuộc tính parents của tệp và sử dụng phương thức files.create để tạo tệp trong thư mục.

Mẫu mã sau đây cho biết cách chèn một tệp vào thư mục bằng thư viện ứng dụng và lệnh curl.

Java

drive/snippets/drive_v3/src/main/java/UploadAppData.java
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

/**
 * Class to demonstrate use-case of create file in the application data folder.
 */
public class UploadAppData {

  /**
   * Creates a file in the application data folder.
   *
   * @return Created file's Id.
   */
  public static String uploadAppData() throws IOException {
        /*Load pre-authorized user credentials from the environment.
        TODO(developer) - See https://developers.google.com/identity for
        guides on implementing OAuth2 for your application.*/
    GoogleCredentials credentials = null;
    try {
      credentials = GoogleCredentials.getApplicationDefault()
          .createScoped(Arrays.asList(DriveScopes.DRIVE_APPDATA));
    } catch (IOException e) {
      e.printStackTrace();
    }
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    Drive service = new Drive.Builder(new NetHttpTransport(),
        GsonFactory.getDefaultInstance(),
        requestInitializer)
        .setApplicationName("Drive samples")
        .build();
    try {
      // File's metadata.
      File fileMetadata = new File();
      fileMetadata.setName("config.json");
      fileMetadata.setParents(Collections.singletonList("appDataFolder"));
      java.io.File filePath = new java.io.File("files/config.json");
      FileContent mediaContent = new FileContent("application/json", filePath);
      File file = service.files().create(fileMetadata, mediaContent)
          .setFields("id")
          .execute();
      System.out.println("File ID: " + file.getId());
      return file.getId();
    } catch (GoogleJsonResponseException e) {
      // TODO(developer) - handle error appropriately
      System.err.println("Unable to create file: " + e.getDetails());
      throw e;
    }
  }

}

Python

drive/snippets/drive-v3/app_data_snippet/upload_appdata.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.http import MediaFileUpload


def upload_appdata():
  """Insert a file in the application data folder and prints file Id.
  Returns : ID's of the inserted files

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # call drive api client
    service = build("drive", "v3", credentials=creds)

    # pylint: disable=maybe-no-member
    file_metadata = {"name": "abc.txt", "parents": ["appDataFolder"]}
    media = MediaFileUpload("abc.txt", mimetype="text/txt", resumable=True)
    file = (
        service.files()
        .create(body=file_metadata, media_body=media, fields="id")
        .execute()
    )
    print(f'File ID: {file.get("id")}')

  except HttpError as error:
    print(f"An error occurred: {error}")
    file = None

  return file.get("id")


if __name__ == "__main__":
  upload_appdata()

Node.js

drive/snippets/drive_v3/appdata_snippets/upload_appdata.js
import fs from 'node:fs';
import {GoogleAuth} from 'google-auth-library';
import {google} from 'googleapis';

/**
 * Uploads a file to the application data folder.
 * @return {Promise<string>} The ID of the uploaded file.
 */
async function uploadAppdata() {
  // Authenticate with Google and get an authorized client.
  // TODO (developer): Use an appropriate auth mechanism for your app.
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive.appdata',
  });

  // Create a new Drive API client (v3).
  const service = google.drive({version: 'v3', auth});

  // The metadata for the file to be uploaded.
  const fileMetadata = {
    name: 'config.json',
    parents: ['appDataFolder'],
  };

  // The media content to be uploaded.
  const media = {
    mimeType: 'application/json',
    body: fs.createReadStream('files/config.json'),
  };

  // Upload the file to the application data folder.
  const file = await service.files.create({
    requestBody: fileMetadata,
    media,
    fields: 'id',
  });

  // Print the ID of the uploaded file.
  console.log('File Id:', file.data.id);
  if (!file.data.id) {
    throw new Error('File ID not found.');
  }
  return file.data.id;
}

PHP

drive/snippets/drive_v3/src/DriveUploadAppData.php
<?php
use Google\Client;
use Google\Service\Drive;
function uploadAppData()
{
   try {
    $client = new Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope(Drive::DRIVE);
    $client->addScope(Drive::DRIVE_APPDATA);
    $driveService = new Drive($client);
    $fileMetadata = new Drive\DriveFile(array(
        'name' => 'config.json',
        'parents' => array('appDataFolder')
    ));
    $content = file_get_contents('../files/config.json');
    $file = $driveService->files->create($fileMetadata, array(
        'data' => $content,
        'mimeType' => 'application/json',
        'uploadType' => 'multipart',
        'fields' => 'id'));
    printf("File ID: %s\n", $file->id);
    return $file->id;

   } catch(Exception $e) {
     echo "Error Message: ".$e;
   }  
}

.NET

drive/snippets/drive_v3/DriveV3Snippets/UploadAppData.cs
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;

namespace DriveV3Snippets
{
    // Class of demonstrate the use of Drive upload app data. 
    public class UploadAppData
    {
        /// <summary>
        /// Insert a file in the application data folder and prints file Id.
        /// </summary>
        /// <param name="filePath">File path to upload.</param>
        /// <returns>ID's of the inserted files, null otherwise.</returns>
        public static string DriveUploadAppData(string filePath)
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(DriveService.Scope.DriveAppdata);

                // Create Drive API service.
                var service = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive API Snippets"
                });
                var fileMetadata = new Google.Apis.Drive.v3.Data.File()
                {
                    Name = "config.json",
                    Parents = new List<string>()
                    {
                        "appDataFolder"
                    }
                };
                FilesResource.CreateMediaUpload request;
                using (var stream = new FileStream(filePath,
                           FileMode.Open))
                {
                    request = service.Files.Create(
                        fileMetadata, stream, "application/json");
                    request.Fields = "id";
                    request.Upload();
                }

                var file = request.ResponseBody;
                // Prints the file id.
                Console.WriteLine("File ID: " + file.Id);
                return file.Id;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

curl

Yêu cầu:

curl --request POST \
'https://content.googleapis.com/drive/v3/files' \
    -H 'authorization: Bearer ACCESS_TOKEN' \
    -H 'content-type: application/json' \
    -H 'x-origin: https://explorer.apis.google.com' \
    --data-raw '{"name": "config.json", "parents":["appDataFolder"]}'

Thay thế ACCESS_TOKEN bằng mã thông báo OAuth 2.0 của ứng dụng.

Phản hồi:

{
    "kind": "drive#file",
    "id": FILE_ID,
    "name": "config.json",
    "mimeType": "application/json"
}

Để biết thêm thông tin về cách tạo tệp trong thư mục, hãy tham khảo bài viết Tạo và điền dữ liệu vào thư mục.

Tìm kiếm tệp trong thư mục dữ liệu ứng dụng

Để tìm kiếm tệp trong thư mục dữ liệu ứng dụng, hãy đặt trường spaces thành appDataFolder và sử dụng files.list phương thức.

Mẫu mã sau đây cho biết cách tìm kiếm tệp trong thư mục dữ liệu ứng dụng bằng thư viện ứng dụng và lệnh curl.

Java

drive/snippets/drive_v3/src/main/java/ListAppData.java
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Arrays;

/**
 * Class to demonstrate use-case of list 10 files in the application data folder.
 */
public class ListAppData {

  /**
   * list down files in the application data folder.
   *
   * @return list of 10 files.
   */
  public static FileList listAppData() throws IOException {
        /*Load pre-authorized user credentials from the environment.
        TODO(developer) - See https://developers.google.com/identity for
        guides on implementing OAuth2 for your application.*/
    GoogleCredentials credentials = null;
    try {
      credentials = GoogleCredentials.getApplicationDefault()
          .createScoped(Arrays.asList(DriveScopes.DRIVE_APPDATA));
    } catch (IOException e) {
      e.printStackTrace();
    }
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    Drive service = new Drive.Builder(new NetHttpTransport(),
        GsonFactory.getDefaultInstance(),
        requestInitializer)
        .setApplicationName("Drive samples")
        .build();
    try {
      FileList files = service.files().list()
          .setSpaces("appDataFolder")
          .setFields("nextPageToken, files(id, name)")
          .setPageSize(10)
          .execute();
      for (File file : files.getFiles()) {
        System.out.printf("Found file: %s (%s)\n",
            file.getName(), file.getId());
      }

      return files;
    } catch (GoogleJsonResponseException e) {
      // TODO(developer) - handle error appropriately
      System.err.println("Unable to list files: " + e.getDetails());
      throw e;
    }
  }

}

Python

drive/snippets/drive-v3/app_data_snippet/list_appdata.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def list_appdata():
  """List all files inserted in the application data folder
  prints file titles with Ids.
  Returns : List of items

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # call drive api client
    service = build("drive", "v3", credentials=creds)

    # pylint: disable=maybe-no-member
    response = (
        service.files()
        .list(
            spaces="appDataFolder",
            fields="nextPageToken, files(id, name)",
            pageSize=10,
        )
        .execute()
    )
    for file in response.get("files", []):
      # Process change
      print(f'Found file: {file.get("name")}, {file.get("id")}')

  except HttpError as error:
    print(f"An error occurred: {error}")
    response = None

  return response.get("files")


if __name__ == "__main__":
  list_appdata()

Node.js

drive/snippets/drive_v3/appdata_snippets/list_appdata.js
/**
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import {GoogleAuth} from 'google-auth-library';
import {google} from 'googleapis';

/**
 * Lists all files in the application data folder.
 * @return {Promise<object[]>} A list of files.
 */
async function listAppdata() {
  // Authenticate with Google and get an authorized client.
  // TODO (developer): Use an appropriate auth mechanism for your app.
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive.appdata',
  });

  // Create a new Drive API client (v3).
  const service = google.drive({version: 'v3', auth});

  // List the files in the application data folder.
  const result = await service.files.list({
    spaces: 'appDataFolder',
    fields: 'nextPageToken, files(id, name)',
    pageSize: 100,
  });

  // Print the name and ID of each file.
  (result.data.files ?? []).forEach((file) => {
    console.log('Found file:', file.name, file.id);
  });

  return result.data.files ?? [];
}

export {listAppdata};

PHP

drive/snippets/drive_v3/src/DriveListAppData.php
<?php
use Google\Client;
use Google\Service\Drive;
function listAppData()
{
    try {
        $client = new Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Drive::DRIVE);
        $driveService = new Drive($client);
        $response = $driveService->files->listFiles(array(
            'spaces' => 'appDataFolder',
            'fields' => 'nextPageToken, files(id, name)',
            'pageSize' => 10
        ));
        foreach ($response->files as $file) {
            printf("Found file: %s (%s)", $file->name, $file->id);
        }
        return $response->files;

    }catch(Exception $e) {
        echo "Error Message: ".$e;
    }

}

.NET

drive/snippets/drive_v3/DriveV3Snippets/ListAppData.cs
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;

namespace DriveV3Snippets
{
    // Class to demonstrate use-case of Drive's list files in the application data folder.
    public class ListAppData
    {
        /// <summary>
        /// List down files in the application data folder.
        /// </summary>
        /// <returns>list of 10 files, null otherwise.</returns>
        public static FileList DriveListAppData()
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(DriveService.Scope.DriveAppdata);

                // Create Drive API service.
                var service = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive API Snippets"
                });

                var request = service.Files.List();
                request.Spaces = "appDataFolder";
                request.Fields = "nextPageToken, files(id, name)";
                request.PageSize = 10;
                var result = request.Execute();
                foreach (var file in result.Files)
                {
                    // Prints the list of 10 file names.
                    Console.WriteLine("Found file: {0} ({1})", file.Name, file.Id);
                }
                return result;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

curl

Yêu cầu:

curl \
    -X GET \
    -H "Authorization: Bearer ACCESS_TOKEN" \
    "https://www.googleapis.com/drive/v3/files?spaces=appDataFolder&fields=files(id,name,mimeType,size,modifiedTime)"

Thay thế ACCESS_TOKEN bằng mã thông báo OAuth 2.0 của ứng dụng.

Phản hồi:

{
    "files": [
        {
            "mimeType": "application/json",
            "size": "256",
            "id": FILE_ID,
            "name": "config.json",
            "modifiedTime": "2025-04-03T23:40:05.860Z"
        },
        {
            "mimeType": "text/plain",
            "size": "128",
            "id": FILE_ID,
            "name": "user_settings.txt",
            "modifiedTime": "2025-04-02T17:52:29.020Z"
        }
    ]
}

Tải tệp xuống từ thư mục dữ liệu ứng dụng

Để tải một tệp xuống từ thư mục dữ liệu ứng dụng, hãy sử dụng phương thức files.get với tham số URL alt=media để truy xuất nội dung tệp trong nội dung phản hồi. Để biết thêm thông tin và để xem các mẫu mã, hãy chuyển đến phần Tải nội dung tệp blob xuống.

Mã mẫu sau đây cho biết cách tải tệp xuống trong thư mục dữ liệu ứng dụng bằng lệnh curl. Nội dung phản hồi sẽ khác nhau tuỳ thuộc vào nội dung đã lưu.

curl

Yêu cầu:

curl \
    -X GET \
    -H "Authorization: Bearer ACCESS_TOKEN" \
    "https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media"

Thay thế nội dung sau:

  • ACCESS_TOKEN: Mã thông báo OAuth 2.0 của ứng dụng.
  • FILE_ID: Mã của tệp mà bạn muốn tải xuống.