首页 > 代码库 > 【WP8】线程安全的StorageHelper

【WP8】线程安全的StorageHelper

WP8以后提供了StorageFile的方式访问文件,StorageFile对文件的操作只提供了异步的支持,包括WP8.1 RT也没有对同步读写文件的支持,可以看出异步在移动开发中的重要性,而且Win8也是通过StorageFile进行文件操作的

跟WP7上的IsolatedStorageFile相比,StorageFile使用起来并不方便,最近总结了一些资料,写了一个通用的类库

StorageFile默认是线程不安全的,如果多个线程同时对文件进行读写会抛出异常,例如多图的场景比较常见

让StorageFile使用起来更加方便,同时提供了线程安全的异步操作,同时也对IsolatedStorageFile(Silverlight)进行了封装

一、StorageFile要点:

  StorageFile

    1、访问文件(两种方式)

    //访问安装目录下的test.txt文件,如果不存在,会抛出FileNotFoundException异常    //1、访问当前目录下的文件    var folder = Package.Current.InstalledLocation;    var storageFile = await folder.GetFileAsync("test.txt");    //2、通过Uri访问文件,Uri为绝对路径    storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///local/test.txt", UriKind.Absolute));    //安装文件目录Uri前缀:ms-appx:///    //本地目录Uri前缀:ms-appdata:///local/

    2、没有提供判断文件是否存在的函数,这里通过异常来判断文件是否存在:

    try    {        await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appdata:///local/{0}", filePath), UriKind.Absolute));        return true;    }    catch (Exception)    {        return false;    }

    3、创建文件

    //如果文件已经存在,会抛出异常    var storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName);    using (var stream = await storageFile.OpenStreamForWriteAsync())    {        stream.Write(data, 0, data.Length);    }

  StorageFolder 

    //创建文件夹(用\\分开,前后都不加\\)    var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("aa\\bb\\cc\\dd");            //访问文件夹    var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync("aa\\bb\\cc\\dd");

二、线程安全

  IsolatedStorageFile的同步操作这里使用线程锁来实现线程安全

    //线程锁    private static readonly object lockObj = new object();    public Stream ReadFile(string filePath)    {        lock (lockObj)        {            using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())            {                if (!storageFile.FileExists(filePath))                {                    throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));                }                using (var fs = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, storageFile))                {                    var stream = new MemoryStream();                    fs.CopyTo(stream);                    stream.Seek(0, SeekOrigin.Begin);                    return stream;                }            }        }    }

  异步线程锁使用 Asynclock,可以在Nuget下载到(Enough.AsyncLock)

  Asynclock提供了两个类:AsyncSemaphore,AsyncLock

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Enough.Async{    public class AsyncSemaphore    {        private readonly static Task _completed = Task.FromResult(true);        private readonly Queue<TaskCompletionSource<bool>> _waiters = new Queue<TaskCompletionSource<bool>>();        private int _currentCount;        public AsyncSemaphore(int initialCount)        {            if (initialCount < 0)            {                throw new ArgumentOutOfRangeException("initialCount");            }            _currentCount = initialCount;        }        public Task WaitAsync()        {            lock (_waiters)            {                if (_currentCount > 0)                {                    _currentCount--;                    return _completed;                }                else                {                    var waiter = new TaskCompletionSource<bool>();                    _waiters.Enqueue(waiter);                    return waiter.Task;                }            }        }        public void Release()        {            TaskCompletionSource<bool> toRelease = null;            lock (_waiters)            {                if (_waiters.Count > 0)                {                    toRelease = _waiters.Dequeue();                }                else                {                    _currentCount++;                }            }            if (toRelease != null)            {                toRelease.SetResult(true);            }        }    }}
AsyncSemaphore
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace Enough.Async{    /// <summary>AsyncLock locks across one or several await calls.    ///     /// </summary>    public class AsyncLock    {        private readonly AsyncSemaphore _semaphore;        private readonly Task<Releaser> _releaser;        public AsyncLock()        {            _semaphore = new AsyncSemaphore(1);            _releaser = Task.FromResult(new Releaser(this));        }        public Task<Releaser> LockAsync()        {            var wait = _semaphore.WaitAsync();            return wait.IsCompleted ?                _releaser :                wait.ContinueWith((_, state) => new Releaser((AsyncLock)state),                    this, CancellationToken.None,                    TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);        }        public struct Releaser : IDisposable        {            private readonly AsyncLock _toRelease;            internal Releaser(AsyncLock toRelease)             {                 _toRelease = toRelease;             }            public void Dispose()            {                if (_toRelease != null)                {                    _toRelease._semaphore.Release();                }            }        }    }}
AsyncLock

三、接口与实现

  提供线程安全的异步操作(IsolatedStorageFile和StorageFile)

  IStorageHelper:提供基本的文件操作相关方法

  约定:     1、文件夹用‘/‘分割,     2、路径不以斜杠‘/‘开头     3、文件夹路径以‘/‘结束
// *************************************************// // 作者:bomo// 小组:WP开发组// 创建日期:2014/8/28 21:49:04// 版本号:V1.00// 说明: 文件操作接口类,提供文件操作的相关方法// // *************************************************// // 修改历史: // Date                WhoChanges        Made // 08/28/2014         bomo         Initial creation //// *************************************************// 约定://   1、文件夹用‘/‘分割,//   2、路径不以斜杠‘/‘开头//   3、文件夹路劲以‘/‘结束using System.IO;using System.Threading.Tasks;namespace TestDemo{    public interface IStorageHelper    {        #region 同步方法        Stream ReadFile(string filePath);        string ReadText(string filePath);        void WriteFile(Stream stream, string filePath, bool replace = false);        void WriteFile(byte[] data, string filePath, bool replace = false);        void WriteText(string text, string filePath, bool replace = false);        bool FileExists(string filePath);        bool DirectoryExists(string directory);        bool DeleteFile(string filePath);        bool DeleteDirectory(string directory, bool isDeleteAll = false);        bool CreateDirectory(string directory);        long GetFileLength(string filePath);        string[] GetFiles(string directory);        string[] GetDirectories(string directory);        /// <summary>        /// 序列号类到文件(Xml)        /// </summary>        void Serialize<T>(string filePath, T obj);        T DeSerialize<T>(string filePath);        void CopyPackageFileToLocal(string source, string target = null, bool replace = false);        void CopyPackageFolderToLocal(string source, string target = null, bool replace = false);        Stream GetResourceStream(string filePath);        #endregion        #region 异步方法        Task<Stream> ReadFileAsync(string filePath);        Task<string> ReadTextAsync(string filePath);        Task WriteFileAsync(Stream stream, string filePath, bool replace = false);        Task WriteFileAsync(byte[] data, string filePath, bool replace = false);        Task WriteTextAsync(string text, string filePath, bool replace = false);        Task<bool> FileExistsAsync(string filePath);        Task<bool> DirectoryExistsAsync(string directory);        Task<bool> DeleteFileAsync(string filePath);        Task<bool> DeleteDirectoryAsync(string directory, bool isDeleteAll = false);        Task<bool> CreateDirectoryAsync(string directory);        Task<ulong> GetFileLengthAsync(string filePath);        Task<string[]> GetFilesAsync(string directory);        Task<string[]> GetDirectoriesAsync(string directory);        Task SerializeAsync<T>(string filePath, T obj);        Task<T> DeSerializeAsync<T>(string filePath);        /// <summary>        /// 拷贝安装目录的文件到本地        /// </summary>        Task CopyPackageFileToLocalAsync(string source, string target = null, bool replace = false);        /// <summary>        /// 拷贝安装目录的文件夹(包括子文件夹和子文件)到本地        /// </summary>        Task CopyPackageFolderToLocalAsync(string source, string target = null, bool replace = false);        Task<Stream> GetResourceStreamAsync(string filePath);                #endregion    }}

  IsolatedStorageFile不支持从安装目录拷贝文件夹,StorageFile不支持同步处理文件

using System;using System.IO;using System.IO.IsolatedStorage;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Xml.Serialization;namespace TestDemo{    public class IsolatedStorageHelper : IStorageHelper    {        private static readonly Enough.Async.AsyncLock asyncLock = new Enough.Async.AsyncLock();        private static readonly object lockObj = new object();        private readonly IsolatedStorageFile storageFile;        public IsolatedStorageHelper()        {            storageFile = IsolatedStorageFile.GetUserStoreForApplication();        }        public Stream Test(string filePath)        {            lock (lockObj)            {                using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())                {                    if (!storageFile.FileExists(filePath))                    {                        throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));                    }                    using (var fs = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, storageFile))                    {                        var stream = new MemoryStream();                        fs.CopyTo(stream);                        stream.Seek(0, SeekOrigin.Begin);                        return stream;                    }                }            }        }        public Stream ReadFile(string filePath)        {            lock (lockObj)            {                if (!storageFile.FileExists(filePath))                {                    throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));                }                using (var fs = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, storageFile))                {                    var stream = new MemoryStream();                    fs.CopyTo(stream);                    stream.Seek(0, SeekOrigin.Begin);                    return stream;                }            }        }        public string ReadText(string filePath)        {            lock (lockObj)            {                using (var stream = new IsolatedStorageFileStream(filePath, FileMode.Open, storageFile))                {                    using (var r = new StreamReader(stream))                    {                        return r.ReadToEnd();                    }                }            }        }        public void WriteFile(Stream stream, string filePath, bool replace = false)        {            WriteFile(ToBytes(stream), filePath, replace);        }        public void WriteFile(byte[] data, string filePath, bool replace = false)        {            lock (lockObj)            {                var directory = Path.GetDirectoryName(filePath);                if (directory != null)                {                    directory = directory.Replace("\\", "/");                    if (!storageFile.DirectoryExists(directory))                    {                        //如果目录不存在,则创建                        storageFile.CreateDirectory(directory);                    }                }                if (storageFile.FileExists(filePath))                {                    if (replace)                    {                        storageFile.DeleteFile(filePath);                    }                    else                    {                        return;                    }                }                using (var fs = new IsolatedStorageFileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, storageFile))                {                    fs.Write(data, 0, data.Length);                }            }        }        public void WriteText(string text, string filePath, bool replace = false)        {            WriteFile(Encoding.UTF8.GetBytes(text), filePath, replace);        }        public bool FileExists(string filePath)        {            lock (lockObj)            {                return storageFile.FileExists(filePath);            }        }        public bool DirectoryExists(string directory)        {            lock (lockObj)            {                return storageFile.DirectoryExists(directory);            }        }        public bool DeleteFile(string filePath)        {            lock (lockObj)            {                if (!storageFile.FileExists(filePath)) return false;                storageFile.DeleteFile(filePath);                return true;            }        }        public bool DeleteDirectory(string directory, bool isDeleteAll)        {            lock (lockObj)            {                if (storageFile.GetFileNames(directory).Length + storageFile.GetDirectoryNames(directory).Length > 0)                {                    if (isDeleteAll)                    {                        DeleteDirectory(directory);                        return true;                    }                    else                    {                        return false;                    }                }                else                {                    storageFile.DeleteDirectory(directory);                    return true;                }            }        }        public bool CreateDirectory(string directory)        {            lock (lockObj)            {                if (storageFile.DirectoryExists(directory)) return false;                storageFile.CreateDirectory(directory);                return true;            }        }        public long GetFileLength(string filePath)        {            lock (lockObj)            {                if (storageFile.FileExists(filePath))                {                    return storageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read).Length;                }                throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));            }        }        public string[] GetFiles(string directory)        {            lock (lockObj)            {                var files = storageFile.GetFileNames(directory);                return files.Select(f => directory + f).ToArray();            }        }        public string[] GetDirectories(string directory)        {            lock (lockObj)            {                var folders = storageFile.GetDirectoryNames(directory);                return folders.Select(f => directory + f).ToArray();            }        }        public void Serialize<T>(string filePath, T obj)        {            lock (lockObj)            {                var directory = Path.GetDirectoryName(filePath);                if (directory != null)                {                    directory = directory.Replace("\\", "/");                    if (!storageFile.DirectoryExists(directory))                    {                        //如果目录不存在,则创建                        storageFile.CreateDirectory(directory);                    }                }                if (storageFile.FileExists(filePath))                {                    storageFile.DeleteFile(filePath);                }                using (                    var fs = new IsolatedStorageFileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write,                        FileShare.None, storageFile))                {                    var serializer = new XmlSerializer(obj.GetType());                    serializer.Serialize(fs, obj);                }            }        }        public T DeSerialize<T>(string filePath)        {            lock (lockObj)            {                if (!storageFile.FileExists(filePath))                {                    throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));                }                var serializer = new XmlSerializer(typeof (T));                using (var fs = storageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))                {                    return (T) serializer.Deserialize(fs);                }            }        }        public void CopyPackageFileToLocal(string source, string target = null, bool replace = false)        {            using (var stream = Application.GetResourceStream(new Uri(source, UriKind.Relative)).Stream)            {                WriteFile(stream, target ?? source, replace);            }        }        public void CopyPackageFolderToLocal(string source, string target = null, bool replace = false)        {            throw new NotImplementedException("IsolatedStorageFile不支持拷贝安装文件夹");        }        public Stream GetResourceStream(string filePath)        {            return Application.GetResourceStream(new Uri(filePath, UriKind.Relative)).Stream;        }        public async Task<Stream> ReadFileAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => ReadFile(filePath));            }        }        public async Task<string> ReadTextAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => ReadText(filePath));            }        }        public async Task WriteFileAsync(Stream stream, string filePath, bool replace = false)        {            await WriteFileAsync(ToBytes(stream), filePath, replace);        }        public async Task WriteFileAsync(byte[] data, string filePath, bool replace = false)        {            using (await asyncLock.LockAsync())            {                await Task.Factory.StartNew(() => WriteFile(data, filePath, replace));            }        }        public async Task WriteTextAsync(string text, string filePath, bool replace = false)        {            await WriteFileAsync(Encoding.UTF8.GetBytes(text), filePath, replace);        }        public async Task<bool> FileExistsAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => FileExists(filePath));            }        }        public async Task<bool> DirectoryExistsAsync(string directory)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => DirectoryExists(directory));            }        }        public async Task<bool> DeleteFileAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(() => DeleteFileAsync(filePath));            }        }        public async Task<bool> DeleteDirectoryAsync(string directory, bool isDeleteAll = false)        {             using (await asyncLock.LockAsync())             {                 return await Task.Factory.StartNew(() => DeleteDirectory(directory, isDeleteAll));             }                 }        public async Task<bool> CreateDirectoryAsync(string directory)        {           using (await asyncLock.LockAsync())           {               return await Task.Factory.StartNew(() => CreateDirectory(directory));           }        }        public async Task<ulong> GetFileLengthAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => (ulong)GetFileLength(filePath));            }        }        public async Task<string[]> GetFilesAsync(string directory)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => GetFiles(directory));            }        }        public async Task<string[]> GetDirectoriesAsync(string directory)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => GetDirectories(directory));            }        }        public async Task SerializeAsync<T>(string filePath, T obj)        {             using (await asyncLock.LockAsync())             {                 await Task.Factory.StartNew(() => Serialize(filePath, obj));             }        }        public async Task<T> DeSerializeAsync<T>(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() => DeSerialize<T>(filePath));            }        }        public async Task CopyPackageFileToLocalAsync(string source, string target = null, bool replace = false)        {             using (await asyncLock.LockAsync())            {                await Task.Factory.StartNew(() => CopyPackageFileToLocal(source, target, replace));            }        }        public async Task CopyPackageFolderToLocalAsync(string source, string target = null, bool replace = false)        {            using (await asyncLock.LockAsync())            {                await Task.Factory.StartNew(() => CopyPackageFolderToLocal(source, target, replace));            }        }        public async Task<Stream> GetResourceStreamAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await Task.Factory.StartNew(() =>                    Application.GetResourceStream(new Uri(filePath, UriKind.Relative)).Stream);            }        }        #region 辅助函数        //递归删除文件夹        private void DeleteDirectory(string directory)        {            var directories = storageFile.GetDirectoryNames(directory);            foreach (var d in directories)            {                DeleteDirectory(string.Format("{0}{1}/", directory, d));            }            var files = storageFile.GetFileNames(directory);            foreach (var f in files)            {                storageFile.DeleteFile(f);            }        }        private byte[] ToBytes(Stream stream)        {            if (stream.CanSeek)            {                stream.Seek(0, SeekOrigin.Begin);            }            var length = Convert.ToInt32(stream.Length);            var data = http://www.mamicode.com/new byte[length];            stream.Read(data, 0, length);            return data;        }        #endregion    }}
IsolatedStorageHelper
using System;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml.Serialization;using Windows.ApplicationModel;using Windows.Storage;using Enough.Async;using XTuOne.Common.Helpers;namespace TestDemo{    public class StorageHelper : IStorageHelper    {        private static readonly AsyncLock asyncLock = new AsyncLock();        #region 同步方法(StorageFile不支持同步方法)        public Stream ReadFile(string filePath)        {            throw new NotImplementedException();        }        public string ReadText(string filePath)        {            throw new NotImplementedException();        }        public void WriteFile(Stream stream, string filePath, bool replace = false)        {            throw new NotImplementedException();        }        public void WriteFile(byte[] data, string filePath, bool replace = false)        {            throw new NotImplementedException();        }        public void WriteText(string text, string filePath, bool replace = false)        {            throw new NotImplementedException();        }        public bool FileExists(string filePath)        {            throw new NotImplementedException();        }        public bool DirectoryExists(string directory)        {            throw new NotImplementedException();        }        public bool DeleteFile(string filePath)        {            throw new NotImplementedException();        }        public bool DeleteDirectory(string directory, bool isDeleteAll = false)        {            throw new NotImplementedException();        }        public bool CreateDirectory(string directory)        {            throw new NotImplementedException();        }        public long GetFileLength(string filePath)        {            throw new NotImplementedException();        }        public string[] GetFiles(string directory)        {            throw new NotImplementedException();        }        public string[] GetDirectories(string directory)        {            throw new NotImplementedException();        }        public void Serialize<T>(string filePath, T obj)        {            throw new NotImplementedException();        }        public T DeSerialize<T>(string filePath)        {            throw new NotImplementedException();        }        public void CopyPackageFileToLocal(string source, string target = null, bool replace = false)        {            throw new NotImplementedException();        }        public void CopyPackageFolderToLocal(string source, string target = null, bool replace = false)        {            throw new NotImplementedException();        }        public Stream GetResourceStream(string filePath)        {            throw new NotImplementedException();        }        #endregion        #region 异步方法        public async Task<Stream> ReadFileAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        var f = await                            StorageFile.GetFileFromApplicationUriAsync(                                new Uri(string.Format("ms-appdata:///local/{0}", filePath),                                    UriKind.Absolute));                        using (Stream stream = await f.OpenStreamForReadAsync())                        {                            return CopyStream(stream);                        }                    }                    catch (FileNotFoundException)                    {                        throw new FileNotFoundException(string.Format("没有找到文件:{0}", filePath));                    }                });            }        }        public async Task<string> ReadTextAsync(string filePath)        {            using (Stream stream = await ReadFileAsync(filePath))            {                using (var reader = new StreamReader(stream))                {                    return await reader.ReadToEndAsyncThread();                }            }        }        public async Task WriteFileAsync(Stream stream, string filePath, bool replace = false)        {            await WriteFileAsync(ToBytes(stream), filePath, replace);        }        //只支持本地路径        public async Task WriteFileAsync(byte[] data, string filePath, bool replace = false)        {            using (await asyncLock.LockAsync())            {                await await Task.Factory.StartNew(async () =>                {                    //创建文件夹                    //var directory = Path.GetDirectoryName(filePath);                    //if (directory != null)                    //{                    //    directory = directory.Trim(‘/‘).Replace("/", "\\");                    //    await ApplicationData.Current.LocalFolder.CreateFolderAsync(directory,                    //        CreationCollisionOption.OpenIfExists);                    //}                    try                    {                        var f = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appdata:///local/{0}", filePath),                            UriKind.Absolute));                        if (replace)                        {                            await f.DeleteAsync();                        }                        else                        {                            return;                        }                    }                    catch (FileNotFoundException)                    {                        //文件不存在                    }                    //创建文件                    var fileName = filePath.Replace("/", "\\");                    var storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName);                    using (var stream = await storageFile.OpenStreamForWriteAsync())                    {                        stream.Write(data, 0, data.Length);                    }                });            }        }        public async Task WriteTextAsync(string text, string filePath, bool replace = false)        {            await WriteFileAsync(Encoding.UTF8.GetBytes(text), filePath, replace);        }        public async Task<bool> FileExistsAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appdata:///local/{0}", filePath), UriKind.Absolute));                        return true;                    }                    catch (Exception)                    {                        return false;                    }                });            }        }        public async Task<bool> DirectoryExistsAsync(string directory)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        directory = directory.Trim(/).Replace("/", "\\");                        await ApplicationData.Current.LocalFolder.GetFolderAsync(directory);                        return true;                    }                    catch (Exception)                    {                        return false;                    }                });            }        }        public async Task<bool> DeleteFileAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appdata:///local/{0}", filePath), UriKind.Absolute));                        await file.DeleteAsync();                        return true;                    }                    catch (Exception)                    {                        return false;                    }                });            }        }        public async Task<bool> DeleteDirectoryAsync(string directory, bool isDeleteAll = false)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        directory = directory.Trim(/).Replace("/", "\\");                        var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync(directory);                        await folder.DeleteAsync();                        return true;                    }                    catch (Exception)                    {                        return false;                    }                });            }        }        public async Task<bool> CreateDirectoryAsync(string directory)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    try                    {                        directory = directory.Trim(/).Replace("/", "\\");                        await ApplicationData.Current.LocalFolder.CreateFolderAsync(directory, CreationCollisionOption.OpenIfExists);                        return true;                    }                    catch (Exception)                    {                        return false;                    }                });            }        }        public async Task<ulong> GetFileLengthAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    var file = await                        StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appdata:///local/{0}", filePath),                            UriKind.Absolute));                    return (await file.OpenReadAsync()).Size;                });            }        }        public async Task<string[]> GetFilesAsync(string directory)        {            directory = directory.Trim(/).Replace("/", "\\");            var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync(directory);            var files = await folder.GetFilesAsync();            return files.ToList()                .Select(f => f.Path.Replace(ApplicationData.Current.LocalFolder.Path, string.Empty).Trim(\\).Replace("\\", "/"))                .ToArray();        }        public async Task<string[]> GetDirectoriesAsync(string directory)        {            directory = directory.Trim(/).Replace("/", "\\");            var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync(directory);            var files = await folder.GetFoldersAsync();            return files.ToList()                .Select(f => f.Path.Replace(ApplicationData.Current.LocalFolder.Path, string.Empty).Trim(\\).Replace("\\", "/"))                .ToArray();        }        public async Task SerializeAsync<T>(string filePath, T obj)        {            var stream = new MemoryStream();            var serializer = new XmlSerializer(obj.GetType());            serializer.Serialize(stream, obj);            stream.Seek(0, SeekOrigin.Begin);            await WriteFileAsync(stream, filePath, true);        }        public async Task<T> DeSerializeAsync<T>(string filePath)        {            using (var stream = await ReadFileAsync(filePath))            {                var serializer = new XmlSerializer(typeof(T));                return (T)serializer.Deserialize(stream);            }        }        public async Task CopyPackageFileToLocalAsync(string source, string target = null, bool replace = false)        {            using (var stream = await ReadFileAsync(source))            {                await WriteFileAsync(stream, target, replace);            }        }        public async Task CopyPackageFolderToLocalAsync(string source, string target = null, bool replace = false)        {            source = source.Trim(/).Replace("/", "\\");            target = target != null ? target.Trim(/).Replace("/", "\\") : source;            var sourseFolder = await Package.Current.InstalledLocation.GetFolderAsync(source);            //创建目标文件夹            var targetFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(target, CreationCollisionOption.OpenIfExists);            await CopyPackageFolderToLocalAsync(sourseFolder, targetFolder, replace);        }        public async Task CopyPackageFolderToLocalAsync(StorageFolder source, StorageFolder target, bool replace = false)        {            var folders = await source.GetFoldersAsync();            foreach (var storageFolder in folders)            {                var targetFolder = await target.CreateFolderAsync(storageFolder.Name, CreationCollisionOption.OpenIfExists);                await CopyPackageFolderToLocalAsync(storageFolder, targetFolder, replace);            }            var files = await source.GetFilesAsync();            foreach (var storageFile in files)            {                try                {                    await storageFile.CopyAsync(target, storageFile.Name, replace                        ? NameCollisionOption.ReplaceExisting                        : NameCollisionOption.FailIfExists);                }                catch (Exception)                {                    //文件已存在(不替换),抛出异常                }            }        }        public async Task<Stream> GetResourceStreamAsync(string filePath)        {            using (await asyncLock.LockAsync())            {                return await await Task.Factory.StartNew(async () =>                {                    var f = await                        StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appx:///{0}", filePath),                            UriKind.Absolute));                    using (Stream stream = await f.OpenStreamForReadAsync())                    {                        return CopyStream(stream);                    }                });            }        }                #endregion        #region 辅助函数        private static byte[] ToBytes(Stream stream)        {            if (stream.CanSeek)            {                stream.Seek(0, SeekOrigin.Begin);            }            int length = Convert.ToInt32(stream.Length);            var data = http://www.mamicode.com/new byte[length];            stream.Read(data, 0, length);            return data;        }        public Stream CopyStream(Stream stream)        {            if (stream.CanSeek)            {                stream.Seek(0, SeekOrigin.Begin);            }            var tempStream = new MemoryStream();            stream.CopyTo(tempStream);            tempStream.Seek(0, SeekOrigin.Begin);            return tempStream;        }        #endregion    }}
StorageHelper

 

个人能力有限,如果有更好的实现,可以给我留言

转载请注明出处:http://www.cnblogs.com/bomo/p/3942750.html

 

【WP8】线程安全的StorageHelper