05,WP8的文件和存储

内容预告:

  • 特殊的文件夹(Shared/Media,Shared/ShellContent,Shared/Transfer)
  • 用ISET浏览本地文件夹
  • 后台文件传输
  • 使用SD存储卡

但不包括:

  • 本地数据库(基于LINQ的sqlce)
  • SQLite

本地数据存储概览:打包管理器把所有的App放到"安装文件夹",App存储数据到"本地文件夹"。

定位存储位置的不同方式:

WP8文件存储的备选方案:三种方式

// WP7.1 IsolatedStorage APIs
var isf = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream fs = new IsolatedStorageFileStream("CaptainsLog.store", FileMode.Open, isf));...
// WP8 Storage APIs using URI
StorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(                        
new Uri("ms-appdata:///local/CaptainsLog.store "));
...
// WP8 Storage APIs
Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile storageFile = await localFolder.GetFileAsync("CaptainsLog.store");

用WP7.1的方式:

IsolatedStorage类在System.IO.IsolatedStorage命名空间里:

  • IsolatedStorage,在独立存储区表达文件和文件夹
  • IsolatedFileStream,在IsolatedStorage中暴露一个文件流到文件存储。
  • IsolatedStorageSettings,以键值对(Dictionary<TKey,TValue>)方式存储。

保存数据:

private void saveGameToIsolatedStorage(string message)
{
  using (IsolatedStorageFile isf =
         IsolatedStorageFile.GetUserStoreForApplication())
  {
    using (IsolatedStorageFileStream rawStream = isf.CreateFile("MyFile.store"))
    {
       StreamWriter writer = new StreamWriter(rawStream);
       writer.WriteLine(message); // save the message
       writer.Close();
    }
  }
}

读取数据:

private void saveGameToIsolatedStorage(string message)
{
  using (IsolatedStorageFile isf =
         IsolatedStorageFile.GetUserStoreForApplication())
  {
    using (IsolatedStorageFileStream rawStream = isf.CreateFile("MyFile.store"))
    {
       StreamWriter writer = new StreamWriter(rawStream);
       writer.WriteLine(message); // save the message
       writer.Close();
    }
  }
}

保存键值对数据:记着在最后调用Save函数保存。

void saveString(string message, string name)
{
   IsolatedStorageSettings.ApplicationSettings[name] =
     message;

    IsolatedStorageSettings.ApplicationSettings.Save();
}

读取键值对数据:记着要先检查是否有这个键,否则要抛异常。

string loadString(string name)
{
  if (IsolatedStorageSettings.ApplicationSettings.Contains(name))
  {
      return (string)
           IsolatedStorageSettings.ApplicationSettings[name];
    }
    else
        return null;
}

WinPRT的存储方式:在Windows.Storage命名空间下:

  • StorageFolder
  • StorageFile
  • 不支持ApplicationData.LocalSettings,只能用IsolatedStorageSettings或自定义文件

用StorageFolder保存数据:

private async void saveGameToIsolatedStorage(string message)
{
     // Get a reference to the Local Folder
     Windows.Storage.StorageFolder localFolder =          Windows.Storage.ApplicationData.Current.LocalFolder;

    // Create the file in the local folder, or if it already exists, just open it
    Windows.Storage.StorageFile storageFile = 
                await localFolder.CreateFileAsync("Myfile.store",                           CreationCollisionOption.OpenIfExists);

    Stream writeStream = await storageFile.OpenStreamForWriteAsync();
    using (StreamWriter writer = new StreamWriter(writeStream))
    {
        await writer.WriteAsync(logData);
    }}

读取数据:

private async void saveGameToIsolatedStorage(string message)
{
     // Get a reference to the Local Folder
     Windows.Storage.StorageFolder localFolder =          Windows.Storage.ApplicationData.Current.LocalFolder;

    // Create the file in the local folder, or if it already exists, just open it
    Windows.Storage.StorageFile storageFile = 
                await localFolder.CreateFileAsync("Myfile.store",                           CreationCollisionOption.OpenIfExists);

    Stream writeStream = await storageFile.OpenStreamForWriteAsync();
    using (StreamWriter writer = new StreamWriter(writeStream))
    {
        await writer.WriteAsync(logData);
    }}

ms-appdata:/// or ms-appx:/// 保存文件:

// There's no FileExists method in WinRT, so have to try to open it and catch exception instead
  StorageFile storageFile = null;
  bool fileExists = false;

  try  
  {
    // Try to open file using URI
    storageFile = await StorageFile.GetFileFromApplicationUriAsync(
                    new Uri("ms-appdata:///local/Myfile.store"));
    fileExists = true;
  }
  catch (FileNotFoundException)
  {
    fileExists = false;
  }

  if (!fileExists) 
  {
    await ApplicationData.Current.LocalFolder.CreateFileAsync("Myfile.store",CreationCollisionOption.FailIfExists); 
  }
  ...

Windows 8 与 Windows Phone 8 兼容性:

  • WP8下所有的数据存储用LocalFolder(等效于WP7.1下的IsolatedStorage)
  • 不支持漫游数据:ApplicationData.Current.RoamingFolder
  • 临时数据:ApplicationData.Current.RoamingFolder
  • 本地键值对:ApplicationData.Current.LocalSettings
  • 漫游键值对:ApplicationData.Current.RoamingSettings
  • 在Windows8下,可以在用下以代码在XAML元素里加载AppPackages里的图片:
    RecipeImage.Source = new System.Windows.Media.Imaging.BitmapImage(           
    new Uri(@"ms-appx:///Images/french/French_1_600_C.jpg", UriKind.RelativeOrAbsolute));

    在Windows Phone8下,不支持这个URI的语法。只能像Windows Phone7.1那样:

    RecipeImage.Source = new System.Windows.Media.Imaging.BitmapImage("/Images/french/French_1_600_C.jpg");

     

本地文件夹:所有读写的I/O操作仅限于本地文件夹(Local Folder)

 保留文件夹:除一般的存储之外,本地文件夹还用于一些特殊场景:

  • Shared\Media,显示后台播放音乐的艺术家图片。
  • Shared\ShellContent,Tiles的背景图片可以存在这。
  • Shared\Transfer,后台文件传输的存储区域。


数据的序列化:有关数据的持久化

在启动时,从独立存储反序列化。
休眠和墓碑时,序列化并持久存储到独立存储。
激活时,从独立存储反序列化。
终止时,序列化并持久存储到独立存储。

为什么序列化:

序列化可以让内存中的数据集持久存储到文件中,反序列化则可以将文件中的数据读取出来。可以用以下方式做序列化:

  • XmlSerializer
  • DataContractSerializer
  • DataContractJsonSerializer
  • json.net等第三方工具

 DataContractSerializer做序列化:

public class MyDataSerializer<TheDataType>
    {
        public static async Task SaveObjectsAsync(TheDataType sourceData, String targetFileName)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
                targetFileName, CreationCollisionOption.ReplaceExisting);
            var outStream = await file.OpenStreamForWriteAsync();

            DataContractSerializer serializer = new DataContractSerializer(typeof(TheDataType));
            serializer.WriteObject(outStream, sourceData);
            await outStream.FlushAsync();
            outStream.Close();
        }

        ...    }

用的时候:

List<MyDataObjects> myObjects = ...     
await MyDataSerializer<List<MyDataObjects>>.SaveObjectsAsync(myObjects, "MySerializedObjects.xml");

DataContractSerializer反序列化:

public class MyDataSerializer<TheDataType>
    {
        public static async Task<TheDataType> RestoreObjectsAsync(string fileName)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
            var inStream = await file.OpenStreamForReadAsync();

            // Deserialize the objects. 
            DataContractSerializer serializer =
                new DataContractSerializer(typeof(TheDataType));
            TheDataType data = (TheDataType)serializer.ReadObject(inStream);
            inStream.Close();

            return data;
        }
        ...    }

用的时候:

List<MyDataObjects> myObjects
    = await MyDataSerializer<List<MyDataObjects>>.RestoreObjectsAsync("MySerializedObjects.xml");

SD卡存储:必须先在application manifest文件中钩选ID_CAP_REMOVABLE_STORAGE,但不能写文件进去,且只能读取APP注册了的文件关联类型。

声明文件类型关联:WMAppManifest.xml文件中,在Extensions下添加一个FileTypeAssociation元素,Extensions必须紧张着Token元素,且FiteType的ContentType属性是必须的。

<Extensions>  
<FileTypeAssociation Name=“foo" TaskID="_default" NavUriFragment="fileToken=%s">   
 <SupportedFileTypes>      
<FileType ContentType="application/foo">.foo
</FileType>    
</SupportedFileTypes> 
 </FileTypeAssociation>
</Extensions>

读取SD卡的API:

 


配额管理:Windows Phone里没有配额。应用自己必须小心使用空间。除非需要,否则不要使用存储空间,而且要告诉用户用了多少。定时删除不用的内容,并考虑同步或归档数据到云服务上。

同步和线程:当状态信息是复杂的对象时,可以简单地序列化这个对象,序列化可能会比较慢。将加载和保存数据放在一个单独的线程里,以保证程序的可响应性。

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值