קריאה בסטרימינג

‫Cloud Storage תומך בקריאת אובייקטים בסטרימינג, שמאפשרת לאפליקציה או לתהליך לצרוך זרמי בייטים של אובייקטים בזמן אמת ישירות דרך החיבור לרשת, בלי לשמור עותק של הנתונים בדיסק מקומי או באחסון מתמיד.

אם רוצים להוריד אובייקט ולשמור אותו במערכת הקבצים המקומית, צריך לעיין במאמר הורדת אובייקטים כקבצים.

שימוש באימות סיכום ביקורת (checksum) במהלך קריאת סטרימינג

לא כדאי להשתמש בקריאה בסטרימינג אם אתם צריכים אימות סיכום ביקורת (checksum) לפני עיבוד הנתונים. מכיוון שבקריאות סטרימינג בדרך כלל משתמשים בכותרת ה-HTTP‏ Range, ‏Cloud Storage לא מחזיר סיכומי ביקורת (checksum) שחלים רק על חלק שרירותי של נתוני האובייקט שהתבקש. סיכומי ביקורת (checksum) בשרת מאמתים את האובייקט השלם, כלומר אפשר לקרוא ולעבד נתונים פגומים לפני שהסטרימינג המלא מסתיים ומאומת.

התפקידים הנדרשים

כדי לקבל את ההרשאות הנדרשות לקריאות בסטרימינג, צריך לבקש מהאדמין להקצות לכם את התפקיד "צפייה באובייקט אחסון" (roles/storage.objectViewer) בקטגוריה.

התפקיד הזה מכיל את ההרשאה שנדרשת כדי להעביר קריאות בסטרימינג. כדי לראות את ההרשאות הנדרשות, מרחיבים את הקטע Required permissions:

ההרשאות הנדרשות

  • storage.objects.get

יכול להיות שתוכלו לקבל את ההרשאה הזו גם בתפקידים מוגדרים מראש או בתפקידים בהתאמה אישית אחרים.

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

קריאת אובייקט בסטרימינג

הדוגמאות הבאות מראות איך לבצע קריאה בסטרימינג מאובייקט של Cloud Storage לתהליך:

המסוף

מסוף Google Cloud לא תומך בקריאות בסטרימינג. במקום זאת, משתמשים ב-Google Cloud CLI.

שורת הפקודה

  1. מריצים את הפקודה gcloud storage cp תוך שימוש במקף ככתובת ה-URL של היעד, ואז מעבירים את הנתונים לתהליך:

    gcloud storage cp gs://BUCKET_NAME/OBJECT_NAME - | PROCESS_NAME

    כאשר:

    • ‫BUCKET_NAME הוא שם הקטגוריה המכילה את האובייקט. לדוגמה, my_app_bucket.
    • ‫OBJECT_NAME הוא שם האובייקט שמעבירים בסטרימינג לתהליך. לדוגמה, data_measurements.
    • ‫PROCESS_NAME הוא השם של התהליך שאליו מזינים את הנתונים. לדוגמה, analyze_data.

אפשר גם להעביר נתונים בסטרימינג מאובייקט של Cloud Storage לפקודת Linux רגילה, כמו sort:

gcloud storage cp gs://my_app_bucket/data_measurements - | sort

ספריות לקוח

C++

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage C++ API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

namespace gcs = ::google::cloud::storage;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& object_name) {
  gcs::ObjectReadStream stream = client.ReadObject(bucket_name, object_name);

  int count = 0;
  std::string line;
  while (std::getline(stream, line, '\n')) {
    ++count;
  }
  if (stream.bad()) throw google::cloud::Status(stream.status());

  std::cout << "The object has " << count << " lines\n";
}

C#

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage C# API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


using Google.Cloud.Storage.V1;
using System;
using System.IO;

public class DownloadFileSample
{
    public void DownloadFile(
        string bucketName = "your-unique-bucket-name",
        string objectName = "my-file-name",
        string localPath = "my-local-path/my-file-name")
    {
        var storage = StorageClient.Create();
        using var outputFile = File.OpenWrite(localPath);
        storage.DownloadObject(bucketName, objectName, outputFile);
        Console.WriteLine($"Downloaded {objectName} to {localPath}.");
    }
}

Go

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Go API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// downloadFileIntoMemory downloads an object.
func downloadFileIntoMemory(w io.Writer, bucket, object string) ([]byte, error) {
	// bucket := "bucket-name"
	// object := "object-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*50)
	defer cancel()

	rc, err := client.Bucket(bucket).Object(object).NewReader(ctx)
	if err != nil {
		return nil, fmt.Errorf("Object(%q).NewReader: %w", object, err)
	}
	defer rc.Close()

	data, err := io.ReadAll(rc)
	if err != nil {
		return nil, fmt.Errorf("io.ReadAll: %w", err)
	}
	fmt.Fprintf(w, "Blob %v downloaded.\n", object)
	return data, nil
}

Java

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Java API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


import com.google.cloud.ReadChannel;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class StreamObjectDownload {

  public static void streamObjectDownload(
      String projectId, String bucketName, String objectName, String targetFile)
      throws IOException {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of your GCS object
    // String objectName = "your-object-name";

    // The path to the file to download the object to
    // String targetFile = "path/to/your/file";
    Path targetFilePath = Paths.get(targetFile);

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    try (ReadChannel reader = storage.reader(BlobId.of(bucketName, objectName));
        FileChannel targetFileChannel =
            FileChannel.open(targetFilePath, StandardOpenOption.WRITE)) {

      ByteStreams.copy(reader, targetFileChannel);

      System.out.println(
          "Downloaded object "
              + objectName
              + " from bucket "
              + bucketName
              + " to "
              + targetFile
              + " using a ReadChannel.");
    }
  }
}

Node.js

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Node.js API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// The filename and file path where you want to download the file
// const destFileName = '/local/path/to/file.txt';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function streamFileDownload() {
  // The example below demonstrates how we can reference a remote file, then
  // pipe its contents to a local file.
  // Once the stream is created, the data can be piped anywhere (process, sdout, etc)
  await storage
    .bucket(bucketName)
    .file(fileName)
    .createReadStream() //stream is created
    .pipe(fs.createWriteStream(destFileName))
    .on('finish', () => {
      // The file download is complete
    });

  console.log(
    `gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
  );
}

streamFileDownload().catch(console.error);

PHP

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage PHP API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

use Google\Cloud\Storage\StorageClient;

/**
 * Download an object from Cloud Storage and save it as a local file.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $objectName The name of your Cloud Storage object.
 *        (e.g. 'my-object')
 * @param string $destination The local destination to save the object.
 *        (e.g. '/path/to/your/file')
 */
function download_object(string $bucketName, string $objectName, string $destination): void
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->object($objectName);
    $object->downloadToFile($destination);
    printf(
        'Downloaded gs://%s/%s to %s' . PHP_EOL,
        $bucketName,
        $objectName,
        basename($destination)
    );
}

Python

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Python API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from google.cloud import storage


def download_blob_to_stream(bucket_name, source_blob_name, file_obj):
    """Downloads a blob to a stream or other file-like object."""

    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"

    # The ID of your GCS object (blob)
    # source_blob_name = "storage-object-name"

    # The stream or file (file-like object) to which the blob will be written
    # import io
    # file_obj = io.BytesIO()

    storage_client = storage.Client()

    bucket = storage_client.bucket(bucket_name)

    # Construct a client-side representation of a blob.
    # Note `Bucket.blob` differs from `Bucket.get_blob` in that it doesn't
    # retrieve metadata from Google Cloud Storage. As we don't use metadata in
    # this example, using `Bucket.blob` is preferred here.
    blob = bucket.blob(source_blob_name)
    blob.download_to_file(file_obj)

    print(f"Downloaded blob {source_blob_name} to file-like object.")

    return file_obj
    # Before reading from file_obj, remember to rewind with file_obj.seek(0).

Ruby

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Ruby API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

# Downloads a blob to a stream or other file-like object.

# The ID of your GCS bucket
# bucket_name = "your-unique-bucket-name"

# Name of a file in the Storage bucket
# file_name   = "some_file.txt"

# The stream or file (file-like object) to which the contents will be written
# local_file_obj = StringIO.new

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket  = storage.bucket bucket_name
file    = bucket.file file_name

file.download local_file_obj, verify: :none

# rewind the object before starting to read the downloaded contents
local_file_obj.rewind
puts "The full downloaded file contents are: #{local_file_obj.read.inspect}"

Rust

use google_cloud_storage::client::Storage;

pub async fn sample(client: &Storage, bucket_id: &str) -> anyhow::Result<()> {
    const NAME: &str = "object-to-download.txt";
    let mut reader = client
        .read_object(format!("projects/_/buckets/{bucket_id}"), NAME)
        .send()
        .await?;
    println!("counting newlines {NAME} in bucket {bucket_id}");
    let mut count = 0;
    while let Some(buffer) = reader.next().await.transpose()? {
        count += buffer.into_iter().filter(|c| *c == b'\n').count();
    }
    println!("object {NAME} in bucket {bucket_id} contains {count} newlines");
    Ok(())
}

ממשקי API בארכיטקטורת REST

‫API בפורמט JSON

כדי לבצע קריאה בסטרימינג, צריך לפעול לפי ההוראות להורדת אובייקט בהתאם לשיקולים הבאים:

  • לפני שמתחילים לקרוא, מאחזרים את המטא-נתונים של האובייקט ושומרים את מספר הגנרציה שלו. צריך לכלול את מספר הגנרציה הזה בכל אחת מהבקשות, כדי להבטיח שלא תתבצע קריאה של נתונים משתי גנרציות שונות במקרה שבו הגרסה המקורית מוחלפת.

  • משתמשים בכותרת Range בבקשה כדי לאחזר חלק מהאובייקט הכולל, שאותו אפשר לשלוח לתהליך מקומי.

  • ממשיכים לשלוח בקשות לחלקים עוקבים של האובייקט, עד שכל האובייקט מאוחזר.

‫API בפורמט XML

כדי לבצע קריאה בסטרימינג, צריך לפעול לפי ההוראות להורדת אובייקט בהתאם לשיקולים הבאים:

  • לפני שמתחילים לקרוא, מאחזרים את המטא-נתונים של האובייקט ושומרים את מספר הגנרציה שלו. צריך לכלול את מספר הגנרציה הזה בכל אחת מהבקשות, כדי להבטיח שלא תתבצע קריאה של נתונים משתי גנרציות שונות במקרה שבו הגרסה המקורית מוחלפת.

  • משתמשים בכותרת Range בבקשה כדי לאחזר חלק מהאובייקט הכולל, שאותו אפשר לשלוח לתהליך מקומי.

  • ממשיכים לשלוח בקשות לחלקים עוקבים של האובייקט, עד שכל האובייקט מאוחזר.

המאמרים הבאים