读取Google Drive文件时触发FileNotFoundException的问题
解决Google Drive PDF文件读取的FileNotFoundException问题
看起来你踩了一个很容易混淆的坑——System.IO.File.ReadAllBytes是用来读取本地文件系统的文件,根本没法直接访问云端的Google Drive文件!
你说其他文件能正常工作,大概率是那些文件恰好被同步到了你的项目输出目录(就是报错里的C:\Users\JimJam\Documents\Project\GoogleDriveProject\GDriveDownload\bin\Debug\),而这个带空格和长文件名的文件要么没同步到这个本地目录,要么同步到了Google Drive的本地同步文件夹(比如C:\Users\JimJam\Google Drive\),和你代码里默认的当前工作目录不匹配,所以触发了找不到文件的错误。
正确的解决思路:使用Google Drive API读取文件字节
要直接从云端Google Drive读取文件的字节数据,你需要使用Google Drive官方的.NET客户端库,而不是本地文件IO方法。下面是具体的实现步骤:
1. 先安装Google Drive NuGet包
在你的VB项目里安装Google.Apis.Drive.v3包,这是官方的Drive客户端库。
2. 授权并获取Drive服务实例
首先你需要完成Google Drive API的授权(可以用服务账号或者OAuth2授权,根据你的项目场景选择),获取一个DriveService实例。这里举个适合桌面应用的OAuth2授权示例:
Imports Google.Apis.Auth.OAuth2 Imports Google.Apis.Drive.v3 Imports Google.Apis.Services Imports Google.Apis.Util.Store ' 授权范围,这里只需要读取权限 Dim scopes As New List(Of String)() From {DriveService.Scope.DriveReadonly} Dim applicationName As String = "你的应用名称" ' 读取客户端秘钥文件(从Google Cloud控制台下载的json文件) Dim credential As UserCredential Using stream As New FileStream("credentials.json", FileMode.Open, FileAccess.Read) Dim credPath As String = "token.json" credential = GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.FromStream(stream).Secrets, scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result End Using ' 创建Drive服务实例 Dim service As New DriveService(New BaseClientService.Initializer() With { .HttpClientInitializer = credential, .ApplicationName = applicationName })
3. 根据文件名查找Google Drive里的文件
因为你是根据文件名来定位文件,需要先调用API搜索对应的文件:
Dim fileName As String = "1234567_012368547-98884 Street Lane Test.pdf" ' 构建查询:查找文件名匹配,且不是文件夹的文件 Dim listRequest As FilesResource.ListRequest = service.Files.List() listRequest.Q = $"name='{fileName}' and mimeType != 'application/vnd.google-apps.folder'" listRequest.Fields = "files(id, name)" Dim results As IList(Of Google.Apis.Drive.v3.Data.File) = listRequest.Execute().Files If results Is Nothing OrElse results.Count = 0 Then Throw New FileNotFoundException($"Google Drive中未找到文件:{fileName}") End If ' 取第一个匹配的文件(如果有重名的话可能需要额外处理) Dim targetFile As Google.Apis.Drive.v3.Data.File = results(0)
4. 读取文件的字节数据
拿到文件ID后,就可以下载文件的字节内容了:
Dim stream As New MemoryStream() service.Files.Get(targetFile.Id).Download(stream) ' 转换为字节数组 Dim fileBytes As Byte() = stream.ToArray()
额外注意事项
- 如果你确实是用Google Drive本地同步文件夹,那你需要传入完整的同步文件夹路径,而不是只传文件名,比如:
但这种方法依赖本地同步,不如直接用API稳定,尤其是当文件没同步完成或者同步路径变化时容易出错。' 假设你的Google Drive同步目录是这个 Dim fullPath As String = "C:\Users\JimJam\Google Drive\1234567_012368547-98884 Street Lane Test.pdf" Dim file As Byte() = System.IO.File.ReadAllBytes(fullPath) - 文件名里的空格和特殊字符本身不是问题,只要路径正确,
File.ReadAllBytes是能处理的,你之前的错误本质是路径不对,不是文件名的问题。
内容的提问来源于stack exchange,提问作者Jared Scott
相关产品推荐
相关产品推荐

