Upload

最終更新日:2025-08-18 15:54:16

CDNetworks Object Storage において、ユーザーが操作する基本的なデータ単位は「オブジェクト」です。Java SDK では、様々なオブジェクトアップロードインターフェースが提供されており、以下の方法でオブジェクトをアップロードできます。

  • ストリームアップロード
  • ファイルアップロード
  • マルチパートアップロード
  • フォームベースアップロード

SDK では、0KB から 5GB までのオブジェクトアップロードがサポートされています。ストリームアップロードおよびファイルアップロードの場合、コンテンツサイズの上限は 5GB です。より大きなファイルには、各パートが 5GB を超えない範囲で分割可能なマルチパートアップロードを推奨します。フォームベースアップロードは、ブラウザの HTML フォームからオブジェクトをアップロードする方式です。

アップロード時に匿名読み取りアクセスを許可した場合、アップロード完了後、オブジェクトは直接リンクで公開されます。オブジェクトリンクの書式は https://bucket-name.domain/folder-path/object-name です。オブジェクトがバケット直下(ルートディレクトリ)の場合、folder-pathは省略できます。


1. ストリームアップロード

ストリームアップロードは、java.io.InputStream をオブジェクトのデータソースとして利用します。WosClient.putObject を使い、以下のようにデータストリームをアップロードします。

// 文字列(バイト配列)のアップロード
String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// WosClientインスタンス作成
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

String content = "Hello WOS";
wosClient.putObject("bucketname", "objectname", new ByteArrayInputStream(content.getBytes()));

// ネットワークストリームのアップロード
InputStream inputStream = new URL("http://www.a.com").openStream();
wosClient.putObject("bucketname", "objectname", inputStream);

// ファイルストリームのアップロード
FileInputStream fis = new FileInputStream(new File("localfile"));  // フルファイルパスを指定
wosClient.putObject("bucketname", "objectname", fis);

注意:

  1. ローカルファイルの場合は、ファイルストリームよりファイルアップロードを推奨します。
  2. 大容量ファイルはマルチパートアップロードを推奨します。
  3. アップロード可能な最大サイズは5GBです。

2. ファイルアップロード

ファイルアップロードは、ローカルファイルをオブジェクトのデータソースとして利用します。以下はアップロード例です。

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// WosClientインスタンス作成
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

wosClient.putObject("bucketname", "objectname", new File("localfile")); // フルファイルパスを指定

注意: 最大アップロードサイズは5GBです。


3. フォルダー作成

CDNetworks Object Storage はネイティブなフォルダー概念を持たず、バケット内にはオブジェクト(ファイル)のみが保存されます。フォルダー作成は、名前の末尾に / が付いた長さ0のオブジェクトを作成することで実現できます。これらのオブジェクトは通常のオブジェクト同様、ダウンロードや削除が可能です。コンソール上ではフォルダーとして表示されます。

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// WosClientインスタンス作成
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

final String keySuffixWithSlash = "parent_directory/";
wosClient.putObject("bucketname", keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));

// フォルダー内にオブジェクトを作成
wosClient.putObject("bucketname", keySuffixWithSlash + "objectname", new ByteArrayInputStream("Hello WOS".getBytes()));

注意:

  1. フォルダー作成は末尾が / の長さ0オブジェクトを作成するだけです。
  2. ネストされたフォルダーの場合、最終階層のみの作成で十分です(例:src1/src2/src3/ の場合、src1/src2/src3/のみ作成し、src1/src1/src2/ の作成は不要)。

4. オブジェクトメタデータの設定

オブジェクトアップロード時にメタデータを設定できます。メタデータには、オブジェクト長、MIMEタイプ、MD5値(検証用)、ストレージクラス、カスタムユーザーメタデータなどを含みます。メタデータはすべてのアップロード方式(ストリーム、ファイル、マルチパート、コピー)で指定可能です。

各フィールド説明は以下の通りです。

名前 説明 デフォルト値
Content Length
(Content-Length)
アップロードするオブジェクトの長さ。元ソースより大きい値を指定した場合、超過分は切り捨てられます。 実際のストリームまたはファイル長
MIME Type
(Content-Type)
オブジェクト/ファイル種別やページエンコーディングを指定。ブラウザでのオブジェクトの取り扱いに影響。 application/octet-stream
MD5値
(Content-MD5)
オブジェクトのMD5ハッシュ(Base64エンコード)。サーバー側でデータ完全性を検証します。 なし
ストレージクラス オブジェクトのストレージクラス。パフォーマンスやコスト要件に最適なクラスを指定可能。 バケットのストレージクラスと同一
カスタムユーザーメタデータ パーソナライズされたメタデータ。オブジェクトの個別管理用途。 なし

Content-Lengthの設定

ObjectMetadata.setContentLength でオブジェクト長を設定できます。例:

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(1024 * 1024L); // 1MB
wosClient.putObject("bucketname", "objectname", new File("localfile"), metadata);

MIME Typeの設定

ObjectMetadata.setContentType でMIMEタイプを設定可能です。例:

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/jpeg");
wosClient.putObject("bucketname", "objectname.jpg", new File("localimage.jpg"), metadata);

注意: MIMEタイプを設定しない場合は、ファイル拡張子からSDKが自動判別します(例:.xmlapplication/xml.htmltext/html)。

MD5値の設定

ObjectMetadata.setContentMd5 でオブジェクトのMD5値を指定できます。例:

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentMd5("your md5 which should be encoded by base64");
wosClient.putObject("bucketname", "objectname", new File("localimage.jpg"), metadata);

注意:

  • MD5値はBase64エンコードが必要です。
  • サーバーは指定されたMD5値と受信データによる計算値を比較し、一致しない場合アップロードはHTTP 400エラーで失敗します。
  • MD5値を指定しない場合、この検証はスキップされます。
  • WosClient.base64Md5 でMD5値を算出可能です。

ストレージクラスの設定

ObjectMetadata.setObjectStorageClass でストレージクラスを指定できます。例:

ObjectMetadata metadata = new ObjectMetadata();
metadata.setObjectStorageClass(StorageClassEnum.ia); // 低頻度アクセスに設定
wosClient.putObject("bucketname", "objectname", new File("localfile"), metadata);

注意:

  • 未指定時はバケットのストレージクラスが適用されます。
  • ストレージクラスは3種類あり、バケットのストレージクラス同様の意味を持ちます。
  • アーカイブストレージの場合、ダウンロード前にリストアが必要です。

カスタムメタデータの設定

ObjectMetadata.addUserMetadata でユーザーメタデータを追加できます。例:

ObjectMetadata metadata = new ObjectMetadata();
metadata.addUserMetadata("property1", "property-value1");
metadata.getMetadata().put("property2", "property-value2");
wosClient.putObject("bucketname", "objectname", new File("localfile"), metadata);

注意:

  • 上記例ではproperty1とproperty2の2つのカスタムメタデータを設定しています。
  • 複数指定可能ですが、総サイズは8KB以内です。
  • WosClient.getObjectMetadata でカスタムメタデータを取得できます。
  • WosClient.getObjectでオブジェクト取得時にもカスタムメタデータが返されます。

5. マルチパートアップロード

以下のようなケースでマルチパートアップロードが推奨されます。

  • 100MBを超えるファイルのアップロード
  • ネットワークが不安定な場合や帯域幅制限
  • アップロード時点でファイルサイズが不明な場合

メリット:

  • 並列アップロードにより高速化
  • 途中中断時の再開に対応
  • 必要に応じてタスクの一時停止・再開が容易
  • アップロード総サイズの事前把握不要

実装手順:

  1. 初期化(WosClient.initiateMultipartUpload)
  2. パートごとのアップロード(WosClient.uploadPart、順次も並列も可能)
  3. 完了処理(WosClient.completeMultipartUpload)または中止(WosClient.abortMultipartUpload)

初期化

まずマルチパートアップロードを初期化し、必要なパラメータを設定します。戻り値として Upload ID が返却され、以降の処理(中止/クエリ/パート一覧等)で必要となります。

InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest("bucketname", "objectname");
ObjectMetadata metadata = new ObjectMetadata();
metadata.addUserMetadata("property", "property-value");
metadata.setContentType("text/plain");
request.setMetadata(metadata);
InitiateMultipartUploadResult result = wosClient.initiateMultipartUpload(request);

String uploadId = result.getUploadId();
System.out.println("\t" + uploadId);

注意:

  • InitiateMultipartUploadRequest でオブジェクト名・バケット名等を指定します。
  • MIMEタイプ、ストレージクラス、カスタムユーザーメタデータ等も設定可能です。
  • InitiateMultipartUploadResult.getUploadId で以後の操作で必要な一意の Upload ID を取得できます。

パートのアップロード

初期化後、オブジェクト名と Upload ID を指定してパートをアップロードします。各パートは Part Number(110000)で一意に識別され、この番号順で結合されます。既存番号でアップロードすると上書きされます。ラストパート以外は100KB5GBまで、ラストパートは0~5GBまでが許容値です。アップロード順やプロセス・マシンは問いませんが、サーバー側でPart Number順に結合されます。

List<PartEtag> partEtags = new ArrayList<PartEtag>();
// 1つめのパートアップロード
UploadPartRequest request = new UploadPartRequest("bucketname", "objectname");
request.setUploadId(uploadId);
request.setPartNumber(1);
request.setFile(new File("localfile"));
request.setPartSize(5 * 1024 * 1024L);
UploadPartResult result = wosClient.uploadPart(request);
partEtags.add(new PartEtag(result.getEtag(), result.getPartNumber()));

// 2つめのパートアップロード
request = new UploadPartRequest("bucketname", "objectname");
request.setUploadId(uploadId);
request.setPartNumber(2);
request.setFile(new File("localfile"));
request.setOffset(5 * 1024 * 1024L);
request.setPartSize(5 * 1024 * 1024L);
result = wosClient.uploadPart(request);
partEtags.add(new PartEtag(result.getEtag(), result.getPartNumber()));

注意:

  • ラストパート以外は100KB以上である必要があります(完了時に検証)。
  • サーバーは各パートの ETag(MD5)を返します。
  • ファイルの整合性保持のため、localファイルの場合 UploadPartRequest.setAttachMd5(true) でSDK側でMD5自動計算&セット推奨。WOS側で整合性判定します。
  • UploadPartRequest.setContentMd5 を手動で指定した場合、setAttachMd5 より優先されます。
  • パートナンバーは1~10000範囲に収めてください。範囲外は400 Bad Requestとなります。

アップロード完了

すべてのパートをアップロードしたら、完全なパート番号・ETagのリストを渡してオブジェクトとしてマージします。サーバーはすべて検証後、結合します。

List<PartEtag> partEtags = new ArrayList<PartEtag>();
// partEtagsリストには全パートのパート番号とETagが含まれます。

CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest("bucketname", "objectname", uploadId, partEtags);

wosClient.completeMultipartUpload(completeRequest);

注意:

  • partEtagsにはアップロード済みパートのpart番号・ETagをすべて含めてください。
  • パートリストは連続していなくても構いません。

並列マルチパートアップロード

マルチパートアップロード主な強みは大容量ファイルの高信頼・高速アップロードです。下記は並列アップロード例です。

// 初期化部分省略
ExecutorService executorService = Executors.newFixedThreadPool(20);
final File largeFile = new File("localfile");

long partSize = 100 * 1024 * 1024L;
long fileSize = largeFile.length();
long partCount = fileSize % partSize == 0 ? fileSize / partSize : fileSize / partSize + 1;
final List<PartEtag> partEtags = Collections.synchronizedList(new ArrayList<PartEtag>());

for (int i = 0; i < partCount; i++) {
    final long offset = i * partSize;
    final long currPartSize = (i + 1 == partCount) ? fileSize - offset : partSize;
    final int partNumber = i + 1;
    executorService.execute(() -> {
        UploadPartRequest uploadPartRequest = new UploadPartRequest();
        uploadPartRequest.setBucketName(bucketName);
        uploadPartRequest.setObjectKey(objectKey);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setFile(largeFile);
        uploadPartRequest.setPartSize(currPartSize);
        uploadPartRequest.setOffset(offset);
        uploadPartRequest.setPartNumber(partNumber);

        try {
            UploadPartResult uploadPartResult = wosClient.uploadPart(uploadPartRequest);
            System.out.println("Part#" + partNumber + " done\n");
            partEtags.add(new PartEtag(uploadPartResult.getEtag(), uploadPartResult.getPartNumber()));
        } catch (WosException e) {
            e.printStackTrace();
        }
    });
}
executorService.shutdown();
while (!executorService.isTerminated()) {
    executorService.awaitTermination(5, TimeUnit.SECONDS);
}
// 統合処理
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectKey, uploadId, partEtags);
wosClient.completeMultipartUpload(completeMultipartUploadRequest);

注意: マルチパートアップロードでは、各パートのオフセット・長さをUploadPartRequest.setOffsetsetPartSize で指定します。

マルチパートアップロードの中止

マルチパートアップロードタスクは中止可能です。キャンセル後、そのUpload IDは無効となり、当該アップロード済みパートもすべて削除されます。

不要な一時アップロードや失敗タスクも下記のように中止し、ストレージ節約が可能です。

AbortMultipartUploadRequest request = new AbortMultipartUploadRequest("bucketname", "objectname", uploadId);
wosClient.abortMultipartUpload(request);

アップロード済みパートの一覧取得

WosClient.listParts により、指定マルチパートタスクのアップロード済みパート一覧を取得できます。

ListPartsRequest request = new ListPartsRequest("bucketname", "objectname");
request.setUploadId(uploadId);
ListPartsResult result = wosClient.listParts(request);

for (Multipart part : result.getMultipartList()) {
    System.out.println("\t" + part.getPartNumber());   // パート番号
    System.out.println("\t" + part.getSize());         // パートサイズ
    System.out.println("\t" + part.getEtag());         // パートETag
    System.out.println("\t" + part.getLastModified()); // 最終変更日時
}

注意:

  • 1回のリクエストで最大1,000件まで返却されます。Partが1,000件を超える場合は、ListPartsResult.isTruncated() が true になり、ページネーション用に getNextPartNumberMarker() を使用します。
  • 1,000件を超えるタスクは、ページングしてすべてのパートを取得できます。

全パートのページング一覧取得

do {
    result = wosClient.listParts(request);
    for(Multipart part : result.getMultipartList()){
        // パート情報表示
    }
    request.setPartNumberMarker(Integer.parseInt(result.getNextPartNumberMarker()));
} while (result.isTruncated());

マルチパートアップロードタスク一覧取得

WosClient.listMultipartUploads で、全進行中のマルチパートタスク一覧が取得できます。

ListMultipartUploadsRequest request = new ListMultipartUploadsRequest("bucketname");
MultipartUploadListing result = wosClient.listMultipartUploads(request);
for (MultipartUpload upload : result.getMultipartTaskList()) {
    System.out.println("\t" + upload.getUploadId());
    System.out.println("\t" + upload.getObjectKey());
    System.out.println("\t" + upload.getInitiatedDate());
}

注意:

  • 1回のリクエストで1,000件まで返却。必要に応じ isTruncated()getNextKeyMarker()getNextUploadIdMarker() でページングしてください。

ページング例:

do {
    result = wosClient.listMultipartUploads(request);
    for (MultipartUpload upload : result.getMultipartTaskList()) {
        // タスク情報表示
    }
    request.setKeyMarker(result.getNextKeyMarker());
    request.setUploadIdMarker(result.getNextUploadIdMarker());
} while (result.isTruncated());

6. フォームベースアップロード

フォームベースアップロードは、HTMLフォームを用いてバケットにオブジェクトをアップロードする方法です。最大サイズは5GBです。

WosClient.createPostSignature を使用して必要なフォームアップロードパラメータを生成できます。詳細は PostObjectSample をご参考ください。

手順:

  • WosClient.createPostSignature で認証パラメータを生成
  • HTMLフォームを準備
  • 生成したパラメータでフォーム項目を補完
  • ローカルでファイルを選択しフォーム送信 → アップロード

WosClient.createPostSignature により生成される主なパラメータ:

  • policy(フォームの policy フィールド値)
  • signature(フォームの signature フィールド値)

フォームパラメータ生成例:

PostSignatureRequest request = new PostSignatureRequest();
Map<String, Object> formParams = new HashMap<String, Object>();
formParams.put("x-wos-acl", "public-read");             // オブジェクトACL設定
formParams.put("content-type", "text/plain");           // MIMEタイプ設定

request.setFormParams(formParams);
request.setExpires(3600);                               // 有効期間(秒単位)
PostSignatureResponse response = wosClient.createPostSignature(request);

formParams.put("key", objectKey);
formParams.put("policy", response.getPolicy());
formParams.put("accesskeyid", ak);
formParams.put("x-wos-credential", response.getCredential());
formParams.put("x-wos-algorithm", response.getAlgorithm());
formParams.put("bucket", bucketName);
formParams.put("x-wos-date", response.getDate());
formParams.put("x-wos-signature", response.getSignature());

System.out.println("\t" + response.getPolicy());
System.out.println("\t" + response.getSignature());

HTMLフォームのサンプル:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="http://bucketname.your-endpoint/" method="post" enctype="multipart/form-data">
Object key
<input type="text" name="key" value="objectname" />
<p>
ACL
<input type="text" name="x-wos-acl" value="public-read" />
<p>
Content-Type
<input type="text" name="content-type" value="text/plain" />
<p>
<input type="hidden" name="policy" value="*** Provide your policy ***" />
<input type="hidden" name="AccessKeyId" value="*** Provide your access key ***"/>
<input type="hidden" name="signature" value="*** Provide your signature ***"/>
<input name="file" type="file" />
<input name="submit" value="Upload" type="submit" />
</form>
</body>
</html>

注意:

  • HTMLフォームの policy および signature の値は、WosClient.createPostSignature の結果を利用してください。
  • PostDemoとしてフォームサンプルHTMLをダウンロードできます。