我在我的应用中使用了这个(How to unzip files in Windows Phone 8)帖子中的UnZipper类来获取带图片的拉链,但在极少数情况下它会给我这个错误:
类型' System.OutOfMemoryException'的第一次机会异常。发生在System.Windows.ni.dll System.OutOfMemoryException:类型的异常' System.OutOfMemoryException'被扔了。在System.Windows.Application.GetResourceStreamInternal(StreamResourceInfo zipPackageStreamResourceInfo,乌里resourceUri)在System.Windows.Application.GetResourceStream(StreamResourceInfo zipPackageStreamResourceInfo,乌里uriResource)在ImperiaOnline.Plugins.UnZipper.GetFileStream(字符串文件名)在ImperiaOnline.Plugins.IOHelpers.unzip (String zipFilePath,String zipDestinationPath)
设备有两倍以上的空闲内存。有人可以帮我这个。这是我的代码:
public static void unzip(string zipFilePath,string zipDestinationPath) {
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
var dirNames = isolatedStorage.GetDirectoryNames(zipDestinationPath);
bool doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
Debug.WriteLine("Folder does not exists");
isolatedStorage.CreateDirectory(zipDestinationPath);
}
try
{
using (IsolatedStorageFileStream zipFile = isolatedStorage.OpenFile(zipFilePath, FileMode.Open, FileAccess.ReadWrite))
{
UnZipper unzip = new UnZipper(zipFile);
bool isModuleFolderDeleted = false;
foreach (string currentFileAndDirectory in unzip.FileNamesInZip())
{
string[] fileLocations = currentFileAndDirectory.Split('/');
string prefix = zipDestinationPath + '/';
int locationsCount = fileLocations.Length;
string fileName = fileLocations.Last();
string currentPath = prefix;
for (int i = 0; i < locationsCount - 1; i++)
{
dirNames = isolatedStorage.GetDirectoryNames(currentPath + fileLocations[i]);
doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
if (i == 2)
{
isModuleFolderDeleted = true;
}
}
else if (i == 2 && !isModuleFolderDeleted)
{
Debug.WriteLine(currentPath + fileLocations[i] + " is deleted and recreated");
DeleteDirectoryRecursively(isolatedStorage, currentPath + fileLocations[i]);
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
isModuleFolderDeleted = true;
}
currentPath += fileLocations[i] + '/';
}
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
try
{
newFileStream.Write(fileBytes, 0, fileBytes.Length);
}
catch (Exception ex)
{
Debug.WriteLine("FILE WRITE EXCEPTION: " + ex);
newFileStream.Close();
newFileStream = null;
zipFile.Close();
unzip.Dispose();
}
newFileStream.Close();
newFileStream = null;
}
zipFile.Close();
unzip.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
isolatedStorage.DeleteFile(zipFilePath);
}
}
public static void unzip(string zipFilePath,string zipDestinationPath) {
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
var dirNames = isolatedStorage.GetDirectoryNames(zipDestinationPath);
bool doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
Debug.WriteLine("Folder does not exists");
isolatedStorage.CreateDirectory(zipDestinationPath);
}
try
{
using (IsolatedStorageFileStream zipFile = isolatedStorage.OpenFile(zipFilePath, FileMode.Open, FileAccess.ReadWrite))
{
UnZipper unzip = new UnZipper(zipFile);
bool isModuleFolderDeleted = false;
foreach (string currentFileAndDirectory in unzip.FileNamesInZip())
{
string[] fileLocations = currentFileAndDirectory.Split('/');
string prefix = zipDestinationPath + '/';
int locationsCount = fileLocations.Length;
string fileName = fileLocations.Last();
string currentPath = prefix;
for (int i = 0; i < locationsCount - 1; i++)
{
dirNames = isolatedStorage.GetDirectoryNames(currentPath + fileLocations[i]);
doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
if (i == 2)
{
isModuleFolderDeleted = true;
}
}
else if (i == 2 && !isModuleFolderDeleted)
{
Debug.WriteLine(currentPath + fileLocations[i] + " is deleted and recreated");
DeleteDirectoryRecursively(isolatedStorage, currentPath + fileLocations[i]);
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
isModuleFolderDeleted = true;
}
currentPath += fileLocations[i] + '/';
}
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
try
{
newFileStream.Write(fileBytes, 0, fileBytes.Length);
}
catch (Exception ex)
{
Debug.WriteLine("FILE WRITE EXCEPTION: " + ex);
newFileStream.Close();
newFileStream = null;
zipFile.Close();
unzip.Dispose();
}
newFileStream.Close();
newFileStream = null;
}
zipFile.Close();
unzip.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
isolatedStorage.DeleteFile(zipFilePath);
}
}
此处出现此错误:
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName); byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length]; unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length); unzip.GetFileStream(currentFileAndDirectory).Close();
我调试了它,它在
上失败了byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
我检查了GetFileStream方法
public Stream GetFileStream(string filename) { if (fileEntries == null) fileEntries = ParseCentralDirectory(); //We need to do this in case the zip is in a format Silverligth doesn't like long position = this.stream.Position; this.stream.Seek(0, SeekOrigin.Begin); Uri fileUri = new Uri(filename, UriKind.Relative); StreamResourceInfo info = new StreamResourceInfo(this.stream, null); StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri); this.stream.Position = position; if (stream != null) return stream.Stream; return null; }
它会在此行上抛出OutOfMemory异常:
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);