애플리케이션별 데이터 저장

애플리케이션 데이터 폴더는 앱에서 구성 파일과 같은 애플리케이션별 데이터를 저장하는 데 사용할 수 있는 특수한 숨겨진 폴더입니다. 애플리케이션 데이터 폴더는 폴더에서 파일을 만들려고 할 때 자동으로 생성됩니다. 사용자가 직접 상호작용해서는 안 되는 파일을 저장하는 데 이 폴더를 사용하세요. 이 폴더는 앱에서만 액세스할 수 있으며 콘텐츠는 사용자 및 다른 Google Drive 앱에서 숨겨집니다.

애플리케이션 데이터 폴더는 사용자가 내 드라이브에서 앱을 제거할 때 삭제됩니다. 사용자는 앱의 데이터 폴더를 수동으로 삭제할 수도 있습니다.

애플리케이션 데이터 폴더 범위

애플리케이션 데이터 폴더에 액세스하려면 먼저 민감하지 않은 https://www.googleapis.com/auth/drive.appdata 범위에 대한 액세스를 요청해야 합니다. 범위 및 액세스 권한 요청 방법에 관한 자세한 내용은 Google Drive API 범위 선택하기를 참고하세요. 특정 OAuth 2.0 범위에 관한 자세한 내용은 Google API의 OAuth 2.0 범위를 참고하세요.

애플리케이션 데이터 폴더와 Drive 백업 폴더의 차이점

애플리케이션 데이터 폴더는 Drive 백업 폴더와 별개입니다.

애플리케이션 데이터 폴더는 서드 파티 앱별로 생성되는 구성 폴더이며 각 서드 파티 앱은 이 폴더에 데이터를 저장할 수 있습니다. appDataFolder에서 데이터를 만든 애플리케이션만 액세스할 수 있습니다. Drive 사용자 인터페이스 (UI)를 사용하여 폴더에 액세스할 수 없습니다.

Drive 백업 폴더는 Drive에서 기기 백업을 쓰는 예약된 폴더이며 Drive UI에 표시됩니다.

애플리케이션 데이터 폴더 제약조건

애플리케이션 데이터 폴더를 사용할 때는 다음 제약조건이 적용됩니다.

  • 애플리케이션 데이터 폴더 내에서는 파일이나 폴더를 공유할 수 없습니다. 이렇게 하면 notSupportedForAppDataFolderFiles 오류가 발생하며 다음과 같은 오류 메시지가 표시됩니다. '애플리케이션 데이터 폴더 내 파일에 메서드가 지원되지 않습니다.'

  • appDataFolder의 파일을 저장소 위치(스페이스) 간에 이동할 수 없습니다. 이렇게 하면 '애플리케이션 데이터 폴더 내 파일에 메서드가 지원되지 않습니다.'라는 오류 메시지와 함께 notSupportedForAppDataFolderFiles 오류가 발생합니다. 자세한 내용은 파일 구성을 참고하세요.

  • 애플리케이션 데이터 폴더 내의 파일이나 폴더는 휴지통에 버릴 수 없습니다. 이렇게 하면 notSupportedForAppDataFolderFiles 오류와 함께 '애플리케이션 데이터 폴더 내 파일을 휴지통에 버릴 수 없습니다'라는 오류 메시지가 표시됩니다.

애플리케이션 데이터 폴더에 파일 만들기

애플리케이션 데이터 폴더에 파일을 만들려면 파일의 parents 속성에 appDataFolder를 지정하고 files.create 메서드를 사용하여 폴더에 파일을 만듭니다.

다음 코드 샘플은 클라이언트 라이브러리와 curl 명령어를 사용하여 폴더에 파일을 삽입하는 방법을 보여줍니다.

자바

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

Request의 이메일 데이터를 읽습니다.

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로 설정하고 files.list 메서드를 사용합니다.

다음 코드 샘플은 클라이언트 라이브러리와 curl 명령어를 사용하여 애플리케이션 데이터 폴더에서 파일을 검색하는 방법을 보여줍니다.

자바

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

Request의 이메일 데이터를 읽습니다.

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

애플리케이션 데이터 폴더에서 파일 다운로드

애플리케이션 데이터 폴더에서 파일을 다운로드하려면 alt=media URL 매개변수와 함께 files.get 메서드를 사용하여 응답 본문에서 파일 콘텐츠를 가져옵니다. 자세한 내용과 코드 샘플을 보려면 Blob 파일 콘텐츠 다운로드를 참고하세요.

다음 코드 샘플은 curl 명령어를 사용하여 애플리케이션 데이터 폴더의 파일을 다운로드하는 방법을 보여줍니다. 응답 본문은 저장된 항목에 따라 다릅니다.

curl

Request의 이메일 데이터를 읽습니다.

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: 다운로드할 파일의 ID입니다.