使用 Java 來管理 Azure Data Lake Storage Gen2 中的目錄和檔案

此文章說明如何使用 Java,在具有階層命名空間的儲存體帳戶中建立及管理目錄和檔案。

若要了解如何取得、設定及更新目錄和檔案的存取控制清單 (ACL),請參閱使用 Java 管理 Azure Data Lake Storage Gen2 中的 ACL

套件 (Maven) | 範例 | API 參考 | Gen1 對 Gen2 對應 | 提供意見反應

必要條件

  • Azure 訂用帳戶。 如需詳細資訊,請參閱取得 Azure 免費試用

  • 已啟用階層命名空間的儲存體帳戶。 遵循下列指示以建立帳戶。

設定您的專案

若要開始使用,請開啟此頁面,並尋找最新版本的 Java 程式庫。 然後,在文字編輯器中開啟 pom.xml 檔案。 新增參考該版本的相依性項目。

如果您打算使用 Microsoft Entra ID 來驗證用戶端應用程式,請將相依性新增至 Azure 身分識別程式庫。 如需更多資訊,請參閱適用於 Java 的 Azure 身分識別用戶端程式庫

接下來,將這些匯入陳述式新增至您的程式碼檔案。

import com.azure.identity.*;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.util.BinaryData;
import com.azure.storage.file.datalake.*;
import com.azure.storage.file.datalake.models.*;
import com.azure.storage.file.datalake.options.*;

注意

Data Lake 儲存體 上的多重通訊協定存取可讓應用程式同時使用 Blob API 和 Data Lake 儲存體 Gen2 API,以使用已啟用階層命名空間 (HNS) 的記憶體帳戶中的數據。 使用 Data Lake 儲存體 Gen2 特有的功能時,例如目錄作業和 ACL,請使用 Data Lake 儲存體 Gen2 API,如本文所示。

選擇要在指定案例中使用的 API 時,請考慮應用程式的工作負載和需求,以及 HNS 對工作負載和應用程式的已知問題和影響。

授權存取權並連線到資料資源

若要使用此文章中的程式碼範例,您必須建立代表儲存體帳戶的已授權 DataLakeServiceClient 執行個體。 您可以使用 Microsoft Entra ID、帳戶存取密鑰或共用存取簽章 (SAS) 來授權 DataLakeServiceClient 物件。

您可以使用適用於 Java 的 Azure 身分識別用戶端程式庫,向 Microsoft Entra ID 驗證您的應用程式。

建立 DataLakeServiceClient 執行個體,並傳入 DefaultAzureCredential 類別的新執行個體。

static public DataLakeServiceClient GetDataLakeServiceClient(String accountName){
    DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder().build();

    DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClientBuilder()
        .endpoint("https://" + accountName + ".dfs.core.windows.net")
        .credential(defaultCredential)
        .buildClient();

    return dataLakeServiceClient;
}

若要進一步了解如何使用 DefaultAzureCredential 授權資料存取權,請參閱適用於 Java 的 Azure 身分識別用戶端程式庫

建立容器

容器可作為您檔案的檔案系統。 您可以使用下列方法建立容器:

下列程式碼範例會建立容器,並傳回 DataLakeFileSystemClient 物件以供稍後使用:

public DataLakeFileSystemClient CreateFileSystem(
        DataLakeServiceClient serviceClient,
        String fileSystemName) {

    DataLakeFileSystemClient fileSystemClient = serviceClient.createFileSystem(fileSystemName);

    return fileSystemClient;
}

建立目錄

您可以使用下列方法在容器中建立目錄參考:

下列程式碼範例將目錄新增至容器,接著新增子目錄並傳回 DataLakeDirectoryClient 物件以供稍後使用:

public DataLakeDirectoryClient CreateDirectory(
        DataLakeFileSystemClient fileSystemClient,
        String directoryName,
        String subDirectoryName) {

    DataLakeDirectoryClient directoryClient = fileSystemClient.createDirectory(directoryName);

    return directoryClient.createSubdirectory(subDirectoryName);
}

重新命名目錄或移動目錄

您可以使用下列方法來重新命名或移動目錄:

將所需目錄的路徑作為參數傳遞。 下列程式碼範例示範如何重新命名子目錄:

public DataLakeDirectoryClient RenameDirectory(
        DataLakeFileSystemClient fileSystemClient,
        String directoryPath,
        String subdirectoryName,
        String subdirectoryNameNew) {

    DataLakeDirectoryClient directoryClient = fileSystemClient
            .getDirectoryClient(String.join("/", directoryPath, subdirectoryName));

    return directoryClient.rename(
            fileSystemClient.getFileSystemName(),
            String.join("/", directoryPath, subdirectoryNameNew));
}

下列程式碼範例示範如何將子目錄從一個目錄移至另一個目錄:

public DataLakeDirectoryClient MoveDirectory(
        DataLakeFileSystemClient fileSystemClient,
        String directoryPathFrom,
        String directoryPathTo,
        String subdirectoryName) {

    DataLakeDirectoryClient directoryClient = fileSystemClient
            .getDirectoryClient(String.join("/", directoryPathFrom, subdirectoryName));

    return directoryClient.rename(
            fileSystemClient.getFileSystemName(),
            String.join("/", directoryPathTo, subdirectoryName));
}

將檔案上傳至目錄

您可以使用下列方法將內容上傳至現有或新的檔案:

下列程式碼範例示範如何使用 uploadFromFile 方法將本機檔案上傳至目錄:

public void UploadFile(
        DataLakeDirectoryClient directoryClient,
        String fileName) {

    DataLakeFileClient fileClient = directoryClient.getFileClient(fileName);

    fileClient.uploadFromFile("filePath/sample-file.txt");
}

您可以使用此方法建立內容並上傳至新檔案,或者將 overwrite 參數設為 true 以覆寫現有檔案。

將資料附加至檔案

您可以使用下列方法將資料上傳附加至檔案:

下列程式碼範例示範如何使用以下步驟將資料附加至檔案結尾處:

  • 建立 DataLakeFileClient 物件以代表您使用的檔案資源。
  • 使用 DataLakeFileClient.append 方法將資料上傳至檔案。
  • 呼叫 DataLakeFileClient.flush 方法將先前上傳的資料寫入檔案,以完成上傳。
public void AppendDataToFile(
        DataLakeDirectoryClient directoryClient) {

    DataLakeFileClient fileClient = directoryClient.getFileClient("sample-file.txt");
    long fileSize = fileClient.getProperties().getFileSize();

    String sampleData = "Data to append to end of file";
    fileClient.append(BinaryData.fromString(sampleData), fileSize);

    fileClient.flush(fileSize + sampleData.length(), true);
}

從目錄下載

下列程式碼範例示範如何使用以下步驟將檔案從目錄下載至本機檔案:

  • 建立 DataLakeFileClient 物件以代表您要下載的檔案。
  • 使用 DataLakeFileClient.readToFile 方法讀取檔案。 此範例將 overwrite 參數設為 true,藉此覆寫現有檔案。
public void DownloadFile(
        DataLakeDirectoryClient directoryClient,
        String fileName) {

    DataLakeFileClient fileClient = directoryClient.getFileClient(fileName);

    fileClient.readToFile("filePath/sample-file.txt", true);
}

列出目錄內容

您可以使用下列方法列出目錄內容並列舉結果:

列舉結果中的路徑可能會在擷取值時產生多個要求。

下列程式碼範例會列印位於目錄中的每個檔案名稱:

public void ListFilesInDirectory(
        DataLakeFileSystemClient fileSystemClient,
        String directoryName) {

    ListPathsOptions options = new ListPathsOptions();
    options.setPath(directoryName);

    PagedIterable<PathItem> pagedIterable = fileSystemClient.listPaths(options, null);

    java.util.Iterator<PathItem> iterator = pagedIterable.iterator();
    PathItem item = iterator.next();

    while (item != null) {
        System.out.println(item.getName());

        if (!iterator.hasNext()) {
            break;
        }
        item = iterator.next();
    }

}

刪除目錄

您可以使用下列其中一種方法刪除目錄:

下列程式碼範例使用 deleteWithResponse 來刪除非空白的目錄以及該目錄下的所有路徑:

public void DeleteDirectory(
        DataLakeFileSystemClient fileSystemClient,
        String directoryName) {

    DataLakeDirectoryClient directoryClient = fileSystemClient.getDirectoryClient(directoryName);

    // Set to true to delete all paths beneath the directory
    boolean recursive = true;

    directoryClient.deleteWithResponse(recursive, null, null, null);
}

另請參閱