问题描述
实际上,我让它适用于 .pdf
文件,但无法让它适用于 .xls
。
现在我似乎无法让以太币工作。请注意,我已经查看了 jsteadfast 的所有其他帖子,这是我想出的代码。
当我阅读消息时,附件中没有任何内容,.txt
文件中的文本正文和 .pdf
或 .xls
文件中的附件都有 2 个文件在message.BodyParts
。
我只想将附件保存到文件共享中。这是一个 .NET 工作者服务。 Azure 活动目录。邮箱是 Outlook.office365.com。
在我的流中我得到
"WriteTimeout = {stream.WriteTimeout' 抛出了一个类型为 'system.invalidOperationException} 的异常"
using (var imapclient = new ImapClient())
{
imapclient.Connect(mailBox,port,SecureSocketoptions.SslOnConnect,stoppingToken);
imapclient.AuthenticationMechanisms.Remove(authenticationResult.Accesstoken);
imapclient.Authenticate(new SaslMechanismOAuth2(userName,authenticationResult.Accesstoken),stoppingToken);
imapclient.InBox.Open(FolderAccess.ReadWrite);
var messages = imapclient.InBox.Fetch(0,-1,MessageSummaryItems.Full | MessageSummaryItems.UniqueId);
int unnamed = 0;
foreach (var message in messages)
{
var multipart = message.Body as BodyPartMultipart;
var basic = message.Body as BodyPartBasic;
var bodyParts = message.BodyParts.ToList(); //Foreach message.BodyParts bodyParts[0] contains .txt,bodyParts[1] contains .pdf
var archive = imapclient.GetFolder(_archive);
if (multipart != null)
{
foreach (var attachment in bodyParts)
{
if (!string.IsNullOrEmpty(attachment.FileName)) //when it's .pdf it has a FileName
{
var mime = (MimePart)imapclient.InBox.GetBodyPart(message.UniqueId,attachment);
var fileName = mime.FileName;
if (string.IsNullOrEmpty(fileName))
fileName = string.Format("unnamed-{0}",++unnamed);
using (var stream = File.Create(fileName))
{
string[] splitFileName = fileName.Split(".");
fileName = splitFileName[0] + string.Format("_{0:MM-dd-yyyy_HH-mm-ss-fff}",DateTime.Now) + "." + splitFileName[1];
//SaveStreamToDirectory(stream,fileName,armadaTargetDir);
using (var fileStream = new FileStream(Path.Combine(armadaTargetDir,fileName),FileMode.Create,FileAccess.Write))
{
stream.copyTo(fileStream);
}
}
//imapclient.InBox.Moveto(message.UniqueId,archive);
}
}
}
else if (basic != null && basic.IsAttachment)
{
var mime = (MimePart)imapclient.InBox.GetBodyPart(message.UniqueId,basic);
var fileName = mime.FileName;
if (string.IsNullOrEmpty(fileName))
fileName = string.Format("unnamed-{0}",++unnamed);
using (var stream = File.Create(fileName))
mime.ContentObject.Decodeto(stream);
}
}
}
我还尝试了以下代码示例,根据 jsteadfast 应该也能正常工作。正如你在这里看到的,我正在尝试设置 stream.Position。只是要清楚文件正在保存到文件共享。但没有数据。任何帮助将不胜感激。
using (var imapclient = new ImapClient())
{
imapclient.Connect(mailBox,stoppingToken);
imapclient.AuthenticationMechanisms.Remove(authenticationResult.Accesstoken);
imapclient.Authenticate(new SaslMechanismOAuth2(userName,stoppingToken);
imapclient.InBox.Open(FolderAccess.ReadWrite);
var messages = imapclient.InBox.Fetch(0,MessageSummaryItems.Full | MessageSummaryItems.UniqueId);
int unnamed = 0;
IList<UniqueId> uids = imapclient.InBox.Search(SearchQuery.All);
foreach (UniqueId uid in uids)
{
MimeMessage message = imapclient.InBox.GetMessage(uid);
foreach (MimeEntity attachment in message.Attachments)
{
var fileName = attachment.Contentdisposition?.FileName ?? attachment.ContentType.Name;
using (var stream = File.Create(fileName))
{
stream.Flush();
stream.Seek(0,SeekOrigin.Begin);
if (attachment is MessagePart)
{
var rfc822 = (MessagePart)attachment;
rfc822.Message.Writeto(stream);
}
else
{
var part = (MimePart)attachment;
part.Content.Decodeto(stream);
}
SaveStreamToDirectory(stream,armadaTargetDir);
}
}
}
解决方法
查看您的代码:
using (var stream = File.Create(fileName))
{
string[] splitFileName = fileName.Split(".");
fileName = splitFileName[0] + string.Format("_{0:MM-dd-yyyy_HH-mm-ss-fff}",DateTime.Now) + "." + splitFileName[1];
//SaveStreamToDirectory(stream,fileName,armadaTargetDir);
using (var fileStream = new FileStream(Path.Combine(armadaTargetDir,fileName),FileMode.Create,FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
您正在创建一个名为 stream
(将为空)的文件流。然后创建名为 fileStream
的第二个文件流。
接下来,您要将 stream
的内容复制到 fileStream
中,但 stream
是空的,因为您刚刚创建了它,因此它是空的。
在您的第二个代码示例中,方法 SaveStreamToDirectory(stream,armadaTargetDir);
是什么样的?我的猜测是您需要倒带 stream
(也就是返回到位置 0)才能从流中读取数据。
注意:在您的第二个示例中,创建 stream
后,您立即调用 stream.Flush();
,然后调用 stream.Seek(0,SeekOrigin.Begin);
。在创建流后立即执行这些调用都没有任何意义。当您调用 Flush()
时,您是在告诉流将其所有缓冲数据写入文件(但您尚未写入任何内容,那么您为什么要调用 Flush()?)。然后你正在寻找文件的开头,但由于你没有读或写任何东西,你已经在文件的开头,所以没有意义。