Todos los productos
Search
Centro de documentos

Object Storage Service:Descarga de objetos como archivos mediante OSS SDK for Java 1.0

Última actualización: Sep 03, 2026

Descargue un objeto de Object Storage Service (OSS) desde un bucket a un archivo local.

Notas de uso

  • En este tema se utiliza el endpoint público de la región China (Hangzhou). Para acceder a OSS desde otros servicios de Alibaba Cloud en la misma región, use un endpoint interno. Para obtener más información sobre las regiones y endpoints compatibles, consulte Regions and endpoints.

  • En este tema, las credenciales de acceso se obtienen de variables de entorno. Para obtener más información, consulte 配置访问凭证.

  • Este tema muestra cómo crear una instancia de OSSClient con un endpoint de OSS. Para otras configuraciones, como usar un dominio personalizado o autenticarse con credenciales de Security Token Service (STS), consulte Client configuration.

Permisos

Una cuenta de Alibaba Cloud tiene permisos completos de forma predeterminada. Los usuarios y roles de RAM no tienen permisos inicialmente y deben recibir acceso mediante RAM Policy o Bucket Policy.

API

Acción

Descripción

GetObject

oss:GetObject

Descarga un objeto.

oss:GetObjectVersion

Este permiso es obligatorio si especifica la versión del objeto mediante versionId al descargarlo.

kms:Decrypt

Este permiso es obligatorio si los metadatos del objeto contienen X-Oss-Server-Side-Encryption: KMS durante la descarga.

Descarga de un solo objeto

El siguiente ejemplo descarga exampleobject.txt del directorio testfolder de examplebucket a D:\localpath\examplefile.txt:

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GetObjectRequest;
import java.io.File;

public class Demo {

    public static void main(String[] args) throws Exception {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Do not include the bucket name in the full path. Example: testfolder/exampleobject.txt. 
        String objectName = "testfolder/exampleobject.txt";
        // Specify the full path of the local file to which you want to download the object. 
        String pathName = "D:\\localpath\\examplefile.txt";
        // Specify the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou.
        String region = "cn-hangzhou";

        // Create an OSSClient instance. 
        // Call the shutdown method to release associated resources when the OSSClient is no longer in use.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // Download the object to the specified path. If a file that has the same name already exists, the downloaded object overwrites the file. Otherwise, the downloaded object is saved in the path. 
            // If you do not specify the local path for the downloaded object, the downloaded object is saved to the path of the project to which the sample program belongs. 
            ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(pathName));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}   

Descarga por lotes de objetos

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class BatchDownloadObject {
    public static void main(String[] args) throws Exception {
        // Set the Endpoint. Use the China (Hangzhou) region as an example. Set the Endpoint to the actual region.
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the bucket name. Example: examplebucket.
        String bucketName = "examplebuckett";
        // Specify the prefix of the folder to download. Example: "images/". To download the entire bucket, leave this empty.
        String folderPrefix = "";
        // Specify the local download folder.
        String localDownloadPath = "./batch_downloads/";
        // Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou.
        String region = "cn-hangzhou";

        // Create an OSSClient instance.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);

        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // Make sure that the local download folder exists.
            createDirectoryIfNotExists(localDownloadPath);

            // Download objects in batches.
            batchDownloadObjects(ossClient, bucketName, folderPrefix, localDownloadPath);

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * Downloads objects from OSS to a local path in batches.
     * @param ossClient The OSS client.
     * @param bucketName The bucket name.
     * @param folderPrefix The folder prefix.
     * @param localDownloadPath The local download path.
     */
    public static void batchDownloadObjects(OSS ossClient, String bucketName, String folderPrefix, String localDownloadPath) {
        String nextMarker = null;
        ObjectListing objectListing;
        int downloadCount = 0;
        long totalSize = 0;
        int failedCount = 0;

        System.out.println("Starting batch download...");
        System.out.println("Source path: " + bucketName + "/" + folderPrefix);
        System.out.println("Local path: " + localDownloadPath);
        System.out.println("----------------------------------------");

        long startTime = System.currentTimeMillis();

        do {
            // List objects.
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName)
                    .withPrefix(folderPrefix)
                    .withMarker(nextMarker)
                    .withMaxKeys(1000); // List a maximum of 1,000 objects at a time.

            objectListing = ossClient.listObjects(listObjectsRequest);
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();

            for (OSSObjectSummary s : sums) {
                // Skip folders (objects that end with /).
                if (s.getKey().endsWith("/")) {
                    continue;
                }

                try {
                    // Construct the local file path.
                    String localFilePath = constructLocalFilePath(localDownloadPath, s.getKey(), folderPrefix);

                    // Create the parent folder of the local file.
                    File localFile = new File(localFilePath);
                    createDirectoryIfNotExists(localFile.getParent());

                    // Check whether the file exists to avoid repeated downloads.
                    if (localFile.exists() && localFile.length() == s.getSize()) {
                        System.out.println("File already exists. Skip download: " + s.getKey());
                        downloadCount++;
                        totalSize += s.getSize();
                        continue;
                    }

                    // Download the object.
                    System.out.println("Downloading: " + s.getKey() + " -> " + localFilePath);

                    // Use a temporary file to prevent file corruption during download.
                    File tempFile = new File(localFilePath + ".tmp");
                    try {
                        ossClient.getObject(new GetObjectRequest(bucketName, s.getKey()), tempFile);

                        // After the download is complete, rename the temporary file to the final file name.
                        if (tempFile.renameTo(localFile)) {
                            downloadCount++;
                            totalSize += s.getSize();
                            System.out.println("Download complete: " + s.getKey() + " (Size: " + formatFileSize(s.getSize()) + ")");
                        } else {
                            throw new IOException("Failed to rename the temporary file: " + tempFile.getPath() + " -> " + localFile.getPath());
                        }
                    } finally {
                        // Clean up the temporary file.
                        if (tempFile.exists()) {
                            tempFile.delete();
                        }
                    }

                } catch (Exception e) {
                    failedCount++;
                    System.err.println("Failed to download the file: " + s.getKey() + ", Error: " + e.getMessage());
                    // Record detailed error messages for debugging.
                    if (e instanceof OSSException) {
                        OSSException oe = (OSSException) e;
                        System.err.println("OSS Error Code: " + oe.getErrorCode() + ", Request ID: " + oe.getRequestId());
                    }
                }
            }

            nextMarker = objectListing.getNextMarker();
        } while (objectListing.isTruncated());

        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        System.out.println("----------------------------------------");
        System.out.println("Batch download complete!");
        System.out.println("Total number of files downloaded: " + downloadCount);
        System.out.println("Number of failed downloads: " + failedCount);
        System.out.println("Total download size: " + formatFileSize(totalSize));
        System.out.println("Total time elapsed: " + formatDuration(duration));
        System.out.println("Average download speed: " + formatSpeed(totalSize, duration));
    }

    /**
     * Constructs the local file path.
     * @param localDownloadPath The root directory for local downloads.
     * @param objectKey The OSS object key.
     * @param folderPrefix The folder prefix.
     * @return The full path of the local file.
     */
    private static String constructLocalFilePath(String localDownloadPath, String objectKey, String folderPrefix) {
        // Remove the prefix to maintain the relative path structure.
        String relativePath = objectKey;
        if (folderPrefix != null && !folderPrefix.isEmpty() && objectKey.startsWith(folderPrefix)) {
            relativePath = objectKey.substring(folderPrefix.length());
        }

        // Make sure that the path separator is correct.
        String normalizedPath = localDownloadPath.endsWith(File.separator) ?
                localDownloadPath : localDownloadPath + File.separator;

        return normalizedPath + relativePath.replace("/", File.separator);
    }

    /**
     * Creates a folder if it does not exist.
     * @param dirPath The folder path.
     */
    private static void createDirectoryIfNotExists(String dirPath) {
        if (dirPath == null || dirPath.isEmpty()) {
            return;
        }

        try {
            File dir = new File(dirPath);
            if (!dir.exists()) {
                boolean created = dir.mkdirs();
                if (created) {
                    System.out.println("Creating folder: " + dirPath);
                } else if (!dir.exists()) {
                    throw new IOException("Failed to create folder: " + dirPath);
                }
            }
        } catch (Exception e) {
            System.err.println("Failed to create folder: " + dirPath + ", Error: " + e.getMessage());
            throw new RuntimeException("Failed to create folder", e);
        }
    }

    /**
     * Formats the file size.
     * @param size The file size in bytes.
     * @return The formatted file size string.
     */
    private static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.2f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }

    /**
     * Formats the duration.
     * @param duration The duration in milliseconds.
     * @return The formatted duration string.
     */
    private static String formatDuration(long duration) {
        long seconds = duration / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;

        if (hours > 0) {
            return String.format("%d h %d min %d s", hours, minutes % 60, seconds % 60);
        } else if (minutes > 0) {
            return String.format("%d min %d s", minutes, seconds % 60);
        } else {
            return String.format("%d s", seconds);
        }
    }

    /**
     * Formats the download speed.
     * @param totalBytes The total number of bytes.
     * @param durationMs The duration in milliseconds.
     * @return The formatted speed string.
     */
    private static String formatSpeed(long totalBytes, long durationMs) {
        if (durationMs <= 0) {
            return "N/A";
        }

        double bytesPerSecond = (double) totalBytes / (durationMs / 1000.0);

        if (bytesPerSecond < 1024) {
            return String.format("%.2f B/s", bytesPerSecond);
        } else if (bytesPerSecond < 1024 * 1024) {
            return String.format("%.2f KB/s", bytesPerSecond / 1024.0);
        } else if (bytesPerSecond < 1024 * 1024 * 1024) {
            return String.format("%.2f MB/s", bytesPerSecond / (1024.0 * 1024.0));
        } else {
            return String.format("%.2f GB/s", bytesPerSecond / (1024.0 * 1024.0 * 1024.0));
        }
    }
}

Operaciones de API relacionadas

Estos métodos encapsulan la API RESTful. Para llamar directamente a la API, incluya el cálculo de la firma en su código. Para obtener más información, consulte GetObject.

Referencia

  • Código de ejemplo completo para descargar objetos como archivos locales: GitHub.