无法在 UWP (Windows 10 App) C# 中压缩空白文本文件(大小 0KB)
Couldn't zip blank text file (size 0KB) in UWP (Windows 10 App) C#
我有一个 UWP 应用程序(通用 Windows 平台)。我正在尝试压缩文件夹及其内容(子文件夹、图像、文本文件)。
如果文本文件不为空,则效果很好。
但是当任何文本文件为空白或空(0KB 大小)时它会给出异常。
错误如下:
{System.ArgumentException: The specified buffer index is not within the buffer capacity.
at System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer source, UInt32 sourceIndex, Int32 count)
at System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer source)
at SmartflowRuntimes.Service.d__54.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SmartflowRuntimes.Service.d__54.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SmartflowRuntimes.Service.d__53.MoveNext()}
这是我的代码:
public async Task<string> ZipHelper(string zipFileName)
{
try
{
string appFolderPath = ApplicationData.Current.LocalFolder.Path;
StorageFolder destnFolder = await StorageFolder.GetFolderFromPathAsync(appFolderPath + "\destn");
StorageFolder sourceFolder = await StorageFolder.GetFolderFromPathAsync(appFolderPath + "\src");
StorageFile zipFile = await destnFolder.CreateFileAsync(zipFileName, CreationCollisionOption.ReplaceExisting);
Stream zipToCreate = await zipFile.OpenStreamForWriteAsync();
ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Update);
await ZipFolderContents(sourceFolder, archive, sourceFolder.Path);
archive.Dispose();
return "success";
}
catch (Exception ex)
{
return "fail";
}
}
public async Task ZipFolderContents(StorageFolder sourceFolder, ZipArchive archive, string baseDirPath)
{
IReadOnlyList<StorageFile> files = await sourceFolder.GetFilesAsync();
foreach (StorageFile file in files)
{
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, baseDirPath.Length));
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(file));
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
}
IReadOnlyList<StorageFolder> subFolders = await sourceFolder.GetFoldersAsync();
if (subFolders.Count() == 0) return;
foreach (StorageFolder subfolder in subFolders)
await ZipFolderContents(subfolder, archive, baseDirPath);
}
这个问题有解决办法吗?谢谢
此 System.ArgumentException
是从 WindowsRuntimeBufferExtensions.ToArray
方法中抛出的,该方法期望 IBuffer 的大小大于 0。
因此,要解决此问题,请在调用此方法之前检查文件大小,就像您可能经常在调用其方法之前检查对象引用是否为 null 一样。
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, baseDirPath.Length));
ulong fileSize = (await file.GetBasicPropertiesAsync()).Size;
byte[] buffer = fileSize > 0 ? (await FileIO.ReadBufferAsync(file)).ToArray()
: new byte[0];
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
顺便说一句,WindowsRuntimeBufferExtensions.ToArray
是一个 extension method,它使您能够在 IBuffer
实例上调用不存在的 ToArray
方法(因此称为扩展方法) .我也展示了如何以更方便的方式调用它。
我有一个 UWP 应用程序(通用 Windows 平台)。我正在尝试压缩文件夹及其内容(子文件夹、图像、文本文件)。
如果文本文件不为空,则效果很好。
但是当任何文本文件为空白或空(0KB 大小)时它会给出异常。
错误如下:
{System.ArgumentException: The specified buffer index is not within the buffer capacity. at System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer source, UInt32 sourceIndex, Int32 count) at System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer source) at SmartflowRuntimes.Service.d__54.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at SmartflowRuntimes.Service.d__54.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at SmartflowRuntimes.Service.d__53.MoveNext()}
这是我的代码:
public async Task<string> ZipHelper(string zipFileName)
{
try
{
string appFolderPath = ApplicationData.Current.LocalFolder.Path;
StorageFolder destnFolder = await StorageFolder.GetFolderFromPathAsync(appFolderPath + "\destn");
StorageFolder sourceFolder = await StorageFolder.GetFolderFromPathAsync(appFolderPath + "\src");
StorageFile zipFile = await destnFolder.CreateFileAsync(zipFileName, CreationCollisionOption.ReplaceExisting);
Stream zipToCreate = await zipFile.OpenStreamForWriteAsync();
ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Update);
await ZipFolderContents(sourceFolder, archive, sourceFolder.Path);
archive.Dispose();
return "success";
}
catch (Exception ex)
{
return "fail";
}
}
public async Task ZipFolderContents(StorageFolder sourceFolder, ZipArchive archive, string baseDirPath)
{
IReadOnlyList<StorageFile> files = await sourceFolder.GetFilesAsync();
foreach (StorageFile file in files)
{
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, baseDirPath.Length));
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(file));
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
}
IReadOnlyList<StorageFolder> subFolders = await sourceFolder.GetFoldersAsync();
if (subFolders.Count() == 0) return;
foreach (StorageFolder subfolder in subFolders)
await ZipFolderContents(subfolder, archive, baseDirPath);
}
这个问题有解决办法吗?谢谢
此 System.ArgumentException
是从 WindowsRuntimeBufferExtensions.ToArray
方法中抛出的,该方法期望 IBuffer 的大小大于 0。
因此,要解决此问题,请在调用此方法之前检查文件大小,就像您可能经常在调用其方法之前检查对象引用是否为 null 一样。
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, baseDirPath.Length));
ulong fileSize = (await file.GetBasicPropertiesAsync()).Size;
byte[] buffer = fileSize > 0 ? (await FileIO.ReadBufferAsync(file)).ToArray()
: new byte[0];
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
顺便说一句,WindowsRuntimeBufferExtensions.ToArray
是一个 extension method,它使您能够在 IBuffer
实例上调用不存在的 ToArray
方法(因此称为扩展方法) .我也展示了如何以更方便的方式调用它。