אחסון נתונים ספציפיים לאפליקציה

תיקיית נתוני האפליקציה היא תיקייה מוסתרת מיוחדת שבה האפליקציה יכולה לאחסן נתונים ספציפיים לאפליקציה, כמו קובצי תצורה. התיקייה של נתוני האפליקציה נוצרת באופן אוטומטי כשמנסים ליצור בה קובץ. בתיקייה הזו שומרים קבצים שהמשתמש לא אמור לבצע איתם אינטראקציה ישירה. רק לאפליקציה שלכם תהיה גישה לתיקייה הזו, והתוכן שלה יהיה מוסתר מהמשתמש ומאפליקציות אחרות של Google Drive.

התיקייה של נתוני האפליקציה נמחקת כשמשתמש מסיר את האפליקציה מתיקיית 'האחסון שלי'. המשתמשים יכולים גם למחוק את תיקיית הנתונים של האפליקציה באופן ידני.

היקף התיקייה של נתוני האפליקציה

כדי לגשת לתיקיית נתוני האפליקציה, צריך לבקש גישה להיקף https://www.googleapis.com/auth/drive.appdata שאינו רגיש. למידע נוסף על ההיקפים ועל האופן שבו מבקשים גישה אליהם, ראו בחירת היקפים של Google Drive API. למידע נוסף על היקפי הרשאות ספציפיים של OAuth 2.0, ראו היקפי הרשאות של OAuth 2.0 ל-Google APIs.

מה ההבדל בין תיקיית נתוני האפליקציה לתיקיות הגיבוי ב-Drive

התיקייה של נתוני האפליקציה נפרדת מתיקיית הגיבוי ב-Drive.

תיקיית נתוני האפליקציה היא תיקיית תצורה שנוצרת לכל אפליקציה של צד שלישי, וכל אפליקציה של צד שלישי יכולה לאחסן בה נתונים. רק לאפליקציה שיצרה את הנתונים ב-appDataFolder יש גישה אליהם. אי אפשר לגשת לתיקייה באמצעות ממשק המשתמש (UI) של Drive.

תיקיית הגיבוי ב-Drive היא תיקייה שמורה שבה Drive כותב את הגיבויים של המכשיר, והיא מוצגת בממשק המשתמש של Drive.

אילוצים על התיקייה של נתוני האפליקציה

כשעובדים עם התיקייה של נתוני האפליקציה, מתבצעת אכיפה של האילוצים הבאים:

  • אי אפשר לשתף קבצים או תיקיות בתוך התיקייה של נתוני האפליקציה. ניסיון לעשות זאת יגרום לשגיאה notSupportedForAppDataFolderFiles עם הודעת השגיאה הבאה: "Method not supported for files within the Application Data folder".

  • אי אפשר להעביר קבצים ב-appDataFolder בין מיקומי אחסון (מרחבים). ניסיון לעשות זאת יגרום לשגיאה notSupportedForAppDataFolderFiles עם הודעת השגיאה הבאה: "Method not supported for files within the Application Data folder". למידע נוסף, ראו ארגון קבצים.

  • אי אפשר להעביר לאשפה קבצים או תיקיות שנמצאים בתיקיית נתוני האפליקציה. ניסיון לעשות זאת יגרום לשגיאה notSupportedForAppDataFolderFiles עם הודעת השגיאה הבאה: "לא ניתן להעביר לאשפה קבצים בתיקיית Application Data".

יצירת קובץ בתיקיית נתוני האפליקציה

כדי ליצור קובץ בתיקיית נתוני האפליקציה, מציינים את הערך appDataFolder במאפיין parents של הקובץ ומשתמשים ב-method‏ files.create כדי ליצור את הקובץ בתיקייה.

בדוגמת הקוד הבאה מוסבר איך להוסיף קובץ לתיקייה באמצעות ספריית לקוח ופקודת 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
/**
 * Insert a file in the application data folder and prints file Id
 * */
async function uploadAppdata() {
  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app

  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');
  const fs = require('fs');

  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive.appdata',
  });
  const service = google.drive({version: 'v3', auth});
  const fileMetadata = {
    name: 'config.json',
    parents: ['appDataFolder'],
  };
  const media = {
    mimeType: 'application/json',
    body: fs.createReadStream('files/config.json'),
  };
  try {
    const file = await service.files.create({
      requestBody: fileMetadata,
      media: media,
      fields: 'id',
    });
    console.log('File Id:', file.data.id);
    return file.data.id;
  } catch (err) {
    // TODO(developer) - Handle error
    throw err;
  }
}

PHP

drive/snippets/drive_v3/src/DriveUploadAppData.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

בקשה:

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"]}'

מחליפים את ACCESS_TOKEN באסימון OAuth 2.0 של האפליקציה.

תגובה:

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

מידע נוסף על יצירת קבצים בתיקיות זמין במאמר יצירה ויישוב של תיקיות.

חיפוש קבצים בתיקיית נתוני האפליקציה

כדי לחפש קבצים בתיקיית נתוני האפליקציה, מגדירים את השדה spaces לערך appDataFolder ומשתמשים ב-method‏ files.list.

בדוגמת הקוד הבאה מוסבר איך לחפש קבצים בתיקיית נתוני האפליקציה באמצעות ספריית לקוח ופקודת 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.
 */

/**
 * List all files inserted in the application data folder
 * */
async function listAppdata() {
  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app

  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');

  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive.appdata',
  });
  const service = google.drive({version: 'v3', auth});
  try {
    const res = await service.files.list({
      spaces: 'appDataFolder',
      fields: 'nextPageToken, files(id, name)',
      pageSize: 100,
    });
    res.data.files.forEach(function(file) {
      console.log('Found file:', file.name, file.id);
    });
    return res.data.files;
  } catch (err) {
    // TODO(developer) - Handle error
    throw err;
  }
}

module.exports = listAppdata;

PHP

drive/snippets/drive_v3/src/DriveListAppData.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

בקשה:

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

מחליפים את ACCESS_TOKEN באסימון OAuth 2.0 של האפליקציה.

תגובה:

{
    "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"
        }
    ]
}

הורדת קבצים מהתיקייה 'נתוני האפליקציה'

כדי להוריד קובץ מתיקיית נתוני האפליקציה, משתמשים בשיטה files.get עם פרמטר כתובת ה-URL alt=media כדי לאחזר את תוכן הקובץ בגוף התגובה. למידע נוסף ולדוגמאות קוד, אפשר לעיין במאמר הורדת תוכן של קובץ blob.

בדוגמת הקוד הבאה מוסבר איך להוריד קבצים בתיקיית נתוני האפליקציה באמצעות הפקודה curl. גוף התגובה ישתנה בהתאם למה ששומרים.

curl

בקשה:

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

מחליפים את מה שכתוב בשדות הבאים:

  • ACCESS_TOKEN: אסימון OAuth 2.0 של האפליקציה.
  • FILE_ID: המזהה של הקובץ שרוצים להוריד.