我正在使用由Raspberry Pi驱动的系统。作为此过程的一部分,我正尝试从Pi将文本文件上传到我的Google驱动器。作为第一个测试,我有一个UWP应用程序来创建一个温度和湿度数据的文本文件,然后尝试将其上传。
到上载命令时,什么都没有发生。不会引发异常,但不会上传任何文件。我已经在网上搜索了很多死胡同,但是没有错误,我真的不知道从哪里开始找出为什么文件没有上传的原因。我按照Google的指示进行操作,就像我说的那样,没有任何异常可以解决,它只是行不通的。任何建议都将受到欢迎,因为我已经花了很长时间在Google上搜索,但一无所获。>
这是uwp应用程序xaml页面背后的代码的精髓(如果您需要,我可以将整个项目发送给您)。我没有在下面的代码中包含几个方法,因为只是方法StoreValues()
使我暂时感到困惑。这是项目的第一次迭代,没有引发错误。
public sealed partial class MainPage : Page
{
static string[] Scopes = { DriveService.Scope.Drive };
static string AppName = "Drive API .NET Quickstart";
static string fileName = "Environmental_Data";
static string fileExtension = ".txt";
private const int DHTPIN = 4;
private IDht dht = null;
private GpioPin dhtPin = null;
private DispatcherTimer sensorTimer = new DispatcherTimer();
private int counterWrite = 0;
private int counterStore = 0;
//the number on the end of the filename that will be incremented each time a file is produced.
//TODO remove old files and reset counter periodically
private int fileId = 1;
//read values every this many seconds
private int readInterval = 1;
//write a new line to the file every this many readings
private int writeCollectionSize = 2;
//send file to cloud every this many lines
private int storeCollectionSize = 4;
private StorageFolder Folder = ApplicationData.Current.LocalFolder;
public List<Environment> Readings;
public StorageFile File1;
public MainPage()
{
InitializeComponent();
InitializeLocalFiles(fileId);
InitializePi();
}
private async void InitializeLocalFiles(int fileId)
{
try
{
//make a new target file to save our data to
var newFile = $"{fileName}_{fileId.ToString()}{fileExtension}";
File1 = await Folder.CreateFileAsync(newFile, CreationCollisionOption.ReplaceExisting);
File1 = await Folder.GetFileAsync(newFile);
//let a human know where the first file is
Debug.WriteLine(File1.Path);
}
catch (Exception ex)
{
Debug.WriteLine("error incountered in InitializeLocalFiles: {0}", ex.Message);
}
}
private void InitializePi()
{
try
{
//set up the pins etc
dhtPin = GpioController.GetDefault().OpenPin(DHTPIN, GpioSharingMode.Exclusive);
dht = new Dht11(dhtPin, GpioPinDriveMode.Input);
//This is what the environment class looks like: public class Environment
//{ public decimal Temperature; public decimal Humidity; public DateTime DateTime; }
Readings = new List<Environment>();
sensorTimer.Interval = TimeSpan.FromSeconds(readInterval);
//add the tick to the clock and set it going
sensorTimer.Tick += sensorTimer_Tick;
sensorTimer.Start();
//initialise the app
temperatureMeter.Value = "OFF";
humidityMeter.Value = "OFF";
}
catch (Exception ex)
{
Debug.WriteLine("error incountered in InitialisePi: {0}", ex.Message);
}
}
private void sensorTimer_Tick(object sender, object e)
{
try
{
//every tick of the clock, we will read the sensor to get new values
readSensor();
//if we got to the end of the write collection, then it is time to aggregate the figures and write a line to the local file
if (counterWrite == writeCollectionSize)
{
counterWrite = 0;
Readings.AggregateListToCSV(File1);
//clear the list of readings ready for the next tick
Readings.Clear();
}
//if we got to the end of the store collection, it's time to send the local file on a trip around the world
if (counterStore == storeCollectionSize)
{
counterStore = 0;
StoreValues(File1);
//rather than deleting the file, we will make a new one for the next go-round
fileId += 1;
InitializeLocalFiles(fileId);
}
}
catch (Exception ex)
{
Debug.WriteLine("error incountered in sensorTimer_Tick: {0}", ex.Message);
}
}
private async void StoreValues(StorageFile file)
{
try
{
UserCredential credential;
string cred = @"{""installed"":{""client_id"":""* **REDACTED FOR FORUM QUESTION ***"",""redirect_uris"":[""urn:ietf:wg:oauth:2.0:oob"",""http://localhost""]}}";
byte[] byteArray = Encoding.UTF8.GetBytes(cred);
//I'm using credentials stored in memory, but you could use a json file
using (var stream =
//new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
new MemoryStream(byteArray))
{
//TODO find out why I have to copy the token.json file every time to the app folder - for some reason it does not copy over even though set to Copy Always
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
//set up the stuff that the Google Drive seems to require. I don't pretend to understand this bit
DriveService service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = AppName,
});
service.HttpClient.Timeout = TimeSpan.FromMinutes(100);
var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
Name = "My Report",
MimeType = "application/vnd.google-apps.file"
};
FilesResource.CreateMediaUpload request;
//using (var stream = new FileStream(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var stream = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
request = service.Files.Create(fileMetadata, stream, "text/plain");
request.Fields = "id";
await request.UploadAsync();
}
//request.ResponsBody is always NULL - why??
var responseFile = request.ResponseBody;
//this line causes an error "attempted to read or write protected memory"
if (responseFile == null)
{
Debug.WriteLine($"** ERROR ** File {fileName}_{(fileId - 1).ToString()}{fileExtension} could not be uploaded.");
}
else
{
Debug.WriteLine($"File ID: {responseFile.Id.ToString()}");
}
}
catch(Exception ex)
{
Debug.WriteLine("error incountered in StoreValues: {0}", ex.Message);
}
}
}
这将产生一个如下所示的调试输出(显示了一个片段)
....
C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_6.txt
Lines ready to write: 1 | Lines ready to store: 1
** ERROR ** File Environmental_Data_5.txt could not be uploaded.
Lines ready to write: 2 | Lines ready to store: 2
18.9,10.0,2/16/2019 7:32:16 AM
Lines ready to write: 1 | Lines ready to store: 3
Lines ready to write: 2 | Lines ready to store: 4
18.9,9.9,2/16/2019 7:32:19 AM
C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_7.txt
** ERROR ** File Environmental_Data_6.txt could not be uploaded.
Lines ready to write: 1 | Lines ready to store: 1
Lines ready to write: 2 | Lines ready to store: 2
18.9,10.1,2/16/2019 7:32:22 AM
Lines ready to write: 1 | Lines ready to store: 3
Lines ready to write: 2 | Lines ready to store: 4
The thread 0xfac has exited with code 0 (0x0).
Lines ready to write: 1 | Lines ready to store: 1
18.9,10.05,2/16/2019 7:32:25 AM
C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_8.txt
** ERROR ** File Environmental_Data_7.txt could not be uploaded.
Lines ready to write: 2 | Lines ready to store: 2
...
我相信我已经拥有所有的凭证等-每次部署时,我都必须将根据凭证生成的token.jsn文件复制到pi上,但是似乎所有这些都可以正常连接。 / p>
虽然我开始对wpf的开始有了一些了解,但这全都超出了我的理解范围,经过3周的尝试来解决这个问题后,我真的走到了尽头束缚-任何建议都很棒。