英文:
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("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;
}
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<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);
}
}
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 'com.microsoft.azure.storage.StorageException' 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<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());
}
答案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 + "|" + 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");
}
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("Failed to read file content", e);
throw new AzureFileStorageNotAvailableException("Failed to read file");
}
}
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论