如何使用CloudFileClient从Azure文件存储获取文件内容(字节数组)?

huangapple go评论74阅读模式
英文:

How to get file content (byte array) from azure file storage using CloudFileClient?

问题

以下是翻译好的内容:

我在Azure上有文件存储,成功连接并成功地遍历了目录。但是我无法获取文件的内容。为了获得FileClientReference,我使用了以下代码:

public CloudFileClient getFileClientReference() {
    log.info("Logging into azure file storage:");
    CloudFileClient cloudFileClient = null;

    CloudStorageAccount storageAccount;
    try {
        storageAccount = CloudStorageAccount.parse(storageConnectionString);
        cloudFileClient = storageAccount.createCloudFileClient();
    } catch (IllegalArgumentException | URISyntaxException e) {
        log.error("Connection string specifies an invalid URI.");
        log.error("Please confirm the connection string is in the Azure connection string format.");
        throw new AzureFileStorageNotAvailableException("Failed to login to azure file storage.");
    } catch (InvalidKeyException e) {
        log.error("Connection string specifies an invalid key.");
        log.error("Please confirm the AccountName and AccountKey in the connection string are valid.");
        throw new AzureFileStorageNotAvailableException("Failed to login to azure file storage.");
    }
    log.info("Logged into azure file storage.");
    return cloudFileClient;
}

我已经测试过这段代码,它运行正常。我用它遍历了所有的目录。

现在我正在尝试根据给定的URL获取文件内容。我用来获取URL的代码如下:

Iterable<ListFileItem> results = rootDir.listFilesAndDirectories();
for (ListFileItem item : results) {
    boolean isDirectory = item.getClass() == CloudFileDirectory.class;
    final String uri = item.getUri().toString();
    if (isDirectory && uri.contains("myPath")) {
        traverseDirectories((CloudFileDirectory) item, azureFiles);
    } else if (!isDirectory) {
        handleFile(item, uri, azureFiles);
    }
}

最终的结果类似于:

https://appnamedev.file.core.windows.net/mystorage/2018/status/somepdf.pdf

现在我想要使用这个URL以后获取文件内容作为字节数组,为此我使用了以下代码:

fileClientReference.getShareReference(document.getPath())
                   .getRootDirectoryReference().getFileReference(document.getFileName()).openRead();

其中,document.getPath()将指向上述路径,而document.getFileName()将给出文件名:somepdf.pdf。

当我调用这个方法时,我得到一个错误:

Method threw 'com.microsoft.azure.storage.StorageException' exception.
The specified resource name contains invalid characters.

PDF文件是正常的,但我不知道如何访问PDF并获取内容。

英文:

I have file storage on azure and I am connecting and traversing threw the directories successfully. But I can't get the content of the file. For getting the FileClientReference I am using the following code:

public CloudFileClient getFileClientReference() {
    log.info(&quot;Logging into azure file storage:&quot;);
    CloudFileClient cloudFileClient = null;

    CloudStorageAccount storageAccount;
    try {
        storageAccount = CloudStorageAccount.parse(storageConnectionString);
        cloudFileClient = storageAccount.createCloudFileClient();
    } catch (IllegalArgumentException | URISyntaxException e) {
        log.error(&quot;Connection string specifies an invalid URI.&quot;);
        log.error(&quot;Please confirm the connection string is in the Azure connection string format.&quot;);
        throw new AzureFileStorageNotAvailableException(&quot;Failed to login to azure file storage.&quot;);
    } catch (InvalidKeyException e) {
        log.error(&quot;Connection string specifies an invalid key.&quot;);
        log.error(&quot;Please confirm the AccountName and AccountKey in the connection string are valid.&quot;);
        throw new AzureFileStorageNotAvailableException(&quot;Failed to login to azure file storage.&quot;);
    }
    log.info(&quot;Logged into azure file storage.&quot;);
    return cloudFileClient;
}

I have tested this code and it's working fine. I used it to traverse all the directories.
What I am trying now to do is for a given url to get file content. The code that I am using to get the url is:

Iterable&lt;ListFileItem&gt; results = rootDir.listFilesAndDirectories();
    for (ListFileItem item : results) {
        boolean isDirectory = item.getClass() == CloudFileDirectory.class;
        final String uri = item.getUri().toString();
        if (isDirectory &amp;&amp; uri.contains(&quot;myPath&quot;)) {
            traverseDirectories((CloudFileDirectory) item, azureFiles);
        } else if (!isDirectory) {
            handleFile(item, uri, azureFiles);
        }
    }

And in the end the result is something like:

https://appnamedev.file.core.windows.net/mystorage/2018/status/somepdf.pdf

Now I want to use this url to later get the file content as byte array and for that I am using the following code:

 fileClientReference.getShareReference(document.getPath())
                 .getRootDirectoryReference().getFileReference(document.getFileName()).openRead();

Where document.getPath() will point to the above mentioned path and document.getFileName() will give the file name: somepdf.pdf.

When I am calling this method I am getting an error:

Method threw &#39;com.microsoft.azure.storage.StorageException&#39; exception.
The specifed resource name contains invalid characters.

The pdf is ok but I don't know how to access the pdf and get the content.

答案1

得分: 1

public static List<String> extractFileDataFromAzureFileShare(String fileName) throws IOException {
    ShareDirectoryClient directoryClient = new ShareFileClientBuilder()
            .endpoint("https://${accountName}.file.core.windows.net")
            .sasToken("${SASTokenQueryParams}")
            .shareName("${FileShareName}")
            .resourcePath("${FilePath}")
            .buildDirectoryClient();
    ShareFileClient fileClient = directoryClient.getFileClient(fileName);
    byte[] bytes = fileClient.openInputStream().readAllBytes();
    InputStream inputStream = new ByteArrayInputStream(bytes);
    return new BufferedReader(
            new InputStreamReader(inputStream, StandardCharsets.UTF_8))
            .lines()
            .collect(Collectors.toList());
}
英文:
public static List&lt;String&gt; extractFileDataFromAzureFileShare(String fileName) throws IOException {
    ShareDirectoryClient directoryClient = new ShareFileClientBuilder()
            .endpoint(&quot;https://${accountName}.file.core.windows.net&quot;)
            .sasToken(&quot;${SASTokenQueryParams}&quot;)
            .shareName(&quot;${FileShareName}&quot;)
            .resourcePath(&quot;${FilePath}&quot;)
            .buildDirectoryClient();
    ShareFileClient fileClient = directoryClient.getFileClient(fileName);
    byte[] bytes = fileClient.openInputStream().readAllBytes();
    InputStream inputStream = new ByteArrayInputStream(bytes);
    return new BufferedReader(
            new InputStreamReader(inputStream, StandardCharsets.UTF_8))
            .lines()
            .collect(Collectors.toList());
}

答案2

得分: 0

如果有人也在尝试解决这个问题,这里有一个答案:
首先,在调用方法时:

fileClientReference.getShareReference(document.getPath())

路径应该采用以下格式:

/folder1/folder2/folder3/

不包括来自 Azure 的前缀:

https://appnamedev.file.core.windows.net

也不包括之前我尝试过的文件名。我通过对字符串调用 replaceAll 方法来解析它。

在一个方法中,我有:

CloudFile cloudFile;
try {
    String fileLocation = document.getPath().replaceAll(AZURE_FILE_STORAGE_URL_PREFIX + "|" + document.getFileName(), "");
    final CloudFileShare fileShare = fileClientReference.getShareReference(fileLocation);
    cloudFile = fileShare.getRootDirectoryReference().getFileReference(document.getFileName());
    return new AzureFile(document.getFileName(), readFileContent(cloudFile));
} catch (URISyntaxException | StorageException e) {
    log.error("Failed to retrieve file for document with id: {}", documentId, e);
    throw new AzureFileStorageNotAvailableException("Failed to retrieve file");
}

readFileContent 方法如下:

private ByteArrayResource readFileContent(CloudFile cloudFile) {
    try (final FileInputStream fileInputStream = cloudFile.openRead()) {
        final byte[] content = fileInputStream.readAllBytes();
        return new ByteArrayResource(content);
    } catch (StorageException | IOException e) {
        log.error("Failed to read file content", e);
        throw new AzureFileStorageNotAvailableException("Failed to read file");
    }
}

AzureFile 是我自己创建的实体,因为我需要传递文件名和内容:

@Data
@AllArgsConstructor
public class AzureFile {
    private String fileName;
    private ByteArrayResource content;
}
英文:

If anyone is also trying to figure out how to do this here is an answer:
First when you are calling the method:

fileClientReference.getShareReference(document.getPath())

the path should be in the following format:

/folder1/folder2/folder3/

Without the prefix from azure:

https://appnamedev.file.core.windows.net

and without the file name as I was trying before. I have parsed that by calling replaceAll on the string.

In one method I have:

CloudFile cloudFile;
    try {
        String fileLocation = document.getPath().replaceAll(AZURE_FILE_STORAGE_URL_PREFIX + &quot;|&quot; + document.getFileName(), &quot;&quot;);
        final CloudFileShare fileShare = fileClientReference.getShareReference(fileLocation);
        cloudFile = fileShare.getRootDirectoryReference().getFileReference(document.getFileName());
        return new AzureFile(document.getFileName(), readFileContent(cloudFile));
    } catch (URISyntaxException | StorageException e) {
        log.error(&quot;Failed to retrieve file for document with id: {}&quot;, documentId, e);
        throw new AzureFileStorageNotAvailableException(&quot;Failed to retrieve file&quot;);
    }

And the readFileContent method is:

private ByteArrayResource readFileContent(CloudFile cloudFile) {
    try (final FileInputStream fileInputStream = cloudFile.openRead()) {
        final byte[] content = fileInputStream.readAllBytes();
        return new ByteArrayResource(content);
    } catch (StorageException | IOException e) {
        log.error(&quot;Failed to read file content&quot;, e);
        throw new AzureFileStorageNotAvailableException(&quot;Failed to read file&quot;);
    }
}

The AzureFile is an entity that I have created on my own since I needed to pass the file name and the content:

@Data
@AllArgsConstructor
public class AzureFile {

    private String fileName;
    private ByteArrayResource content;
}

huangapple
  • 本文由 发表于 2020年9月30日 00:34:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/64123903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定