WP7独立存储之IsolatedStorageFile之图片的存储和读取

 

wp7的独立存储要用到 IsolatedStorageFile类:获取应用的独立存储区域,可以在该区域里创建、删除目录和文件,可以打开文件(返回文件的流),同时也要用到IsolatedStorageFileStream类:获取独立存储区域的文件的流。
打一个不大恰当的比喻:
IsolatedStorageFIle 相当于一个封闭的大仓库,里面放着很多箱子(相当于目录),箱子可能放着各种货物(相当于各种文件,如txt、jpg等)或者是更小的箱子(目录),
IsolatedStorageFileStream 相当于是仓库的门口,货物的运进运出只能通过从门口出入。
读取不同的文件还要用到不同的流,如文本文件用到 StreamReader 和 StreamWriter ,jpg文件用到 WriteableBitmap类。

Demo项目的界面就一个image控件和两个button控件,一个button的click事件是从图库里读取一张图片到独立存储区,另一个button的click事件是把独立存储区的指定照片读取出来显示到mage控件上。
不废话,直接上代码

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Net;
  5 using System.Windows;
  6 using System.Windows.Controls;
  7 using System.Windows.Documents;
  8 using System.Windows.Input;
  9 using System.Windows.Media;
 10 using System.Windows.Media.Animation;
 11 using System.Windows.Shapes;
 12 using Microsoft.Phone.Controls;
 13 using System.IO.IsolatedStorage;
 14 using Microsoft.Phone.Tasks;
 15 using System.IO;
 16 using System.Windows.Media.Imaging;
 17 using System.Windows.Resources;
 18 
 19 namespace myIsoFile
 20 {
 21     public partial class MainPage : PhoneApplicationPage
 22     {
 23         IsolatedStorageFile isoFile;
 24         IsolatedStorageFileStream isoFileStream;
 25         // 构造函数
 26         public MainPage()
 27         {
 28             InitializeComponent();
 29             this.buttonReadFile.Click += new RoutedEventHandler(buttonReadFile_Click);
 30             this.buttonWriter.Click += new RoutedEventHandler(buttonWriter_Click);
 31 
 32             isoFile = IsolatedStorageFile.GetUserStoreForApplication();
 33 
 34             //创建目录
 35             if (!isoFile.DirectoryExists("picture/myPhoto"))
 36             {
 37                 isoFile.CreateDirectory("picture/myPhoto");
 38             }
 39 
 40             //创建文件。如果创建的文件位于不存在的目录,则同时创建相应目录
 41             if (!isoFile.FileExists("picture\\myPhoto\\123.jpg"))
 42             {
 43               //  isoFile.DeleteFile("picture\\myPhoto\\123.jpg");
 44                 isoFile.CreateFile("picture\\myPhoto\\123.jpg");
 45             }
 46             //else
 47             //{
 48             //    isoFile.DeleteFile("picture\\myPhoto\\123.jpg");
 49             //    isoFile.CreateFile("picture\\myPhoto\\123.jpg");
 50             //}
 51 
 52       //      isoFile.OpenFile("picture\\myPhoto\\123.jpg", FileMode.Open, FileAccess.Write, FileShare.Write);
 53 
 54         }
 55 
 56         //打开图片选择器
 57         void buttonWriter_Click(object sender, RoutedEventArgs e)
 58         {
 59             if (isoFile.FileExists("picture\\myPhoto\\123.jpg"))
 60             {
 61                 var myPhoto = new PhotoChooserTask();
 62                 myPhoto.Completed += new EventHandler<PhotoResult>(myPhoto_Completed);
 63                 myPhoto.Show();
 64             }
 65         }
 66 
 67         //选择完图片之后保存到独立存储区
 68         void myPhoto_Completed(object sender, PhotoResult e)
 69         {
 70             if (e.TaskResult == TaskResult.OK && e.Error == null)
 71             {
 72                 using (isoFileStream = isoFile.OpenFile("picture\\myPhoto\\123.jpg", FileMode.Open, FileAccess.Write, FileShare.Write))
 73                 {
 74 
 75                     //如果是一张已知路径的图片,可以如下获取它的流
 76                     //     Uri uri = new Uri(photoPath, UriKind.Relative); 
 77                     //    StreamResourceInfo sri = Application.GetResourceStream(uri); 
 78                     // sri.stream 表示图片的流
 79 
 80 
 81                     //用所选图片的资源的流创建 BitmapImage
 82                     BitmapImage bitmap = new BitmapImage();
 83 
 84                     //把PhotoChooserTask返回的图片的流直接赋给BitmapImage所谓Source
 85                     bitmap.SetSource(e.ChosenPhoto);
 86 
 87                     //提供一个可写入并可更新的 BitmapSource。
 88                     WriteableBitmap wb = new WriteableBitmap(bitmap);
 89 
 90                     //把wb所表示的图片写到isoFileStream指向的文件,在这里是123.jpg
 91                     wb.SaveJpeg(isoFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
 92 
 93                     //  BitmapImage.SaveJpeg() 其实就是下面这个方法     
 94                     //  Extensions.SaveJpeg(wb, isoFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);  
 95                 }               
 96             }
 97         }
 98 
 99         //从独立存储空间读取图片
100         void buttonReadFile_Click(object sender, RoutedEventArgs e)
101         {
102             if (isoFile.FileExists("picture\\myPhoto\\123.jpg"))
103             {
104                 using (isoFileStream = isoFile.OpenFile("picture\\myPhoto\\123.jpg", FileMode.Open, FileAccess.Read))
105                 {
106                     BitmapImage background = new BitmapImage();
107                     background.SetSource(isoFileStream);
108                     this.image1.Source = background;
109                 }
110 
111             }
112         }
113 
114     }
115 }

 

不过在这里碰到了一个问题,就是在独立存储区的目录下创建文件的问题,如下打开文件 123.jpg就没问题

 1 //创建目录
 2             if (!isoFile.DirectoryExists("picture/myPhoto"))
 3             {
 4                 isoFile.CreateDirectory("picture/myPhoto");
 5             }
 6 
 7             //创建文件。如果创建的文件位于不存在的目录,则同时创建相应目录
 8             if (!isoFile.FileExists("picture\\myPhoto\\123.jpg"))
 9             {
10               //  isoFile.DeleteFile("picture\\myPhoto\\123.jpg");
11                 isoFile.CreateFile("picture\\myPhoto\\123.jpg");
12             }
13             //else
14             //{
15             //    isoFile.DeleteFile("picture\\myPhoto\\123.jpg");
16             //    isoFile.CreateFile("picture\\myPhoto\\123.jpg");
17             //}
18 
19            isoFile.OpenFile("picture\\myPhoto\\123.jpg", FileMode.Open, FileAccess.Write, FileShare.Write);

但如下打开文件 jpg 在运行时就提示出错:

 1 //创建目录
 2             if (!isoFile.DirectoryExists("picture/myPhoto"))
 3             {
 4                 isoFile.CreateDirectory("picture/myPhoto");
 5             }
 6 
 7             //创建文件。如果创建的文件位于不存在的目录,则同时创建相应目录
 8             if (isoFile.FileExists("picture\\myPhoto\\123.jpg"))
 9             {
10                 isoFile.DeleteFile("picture\\myPhoto\\123.jpg");
11                 
12 } 13
14 15 16 isoFile.CreateFile("picture\\myPhoto\\123.jpg"); 17 18 19 isoFile.OpenFile("picture\\myPhoto\\123.jpg", FileMode.Open, FileAccess.Write, FileShare.Write);

也就是说,先删除再创建在运行时打开就出错,不知何解,求答案!

 

终于,思考了一天,找到答案了。

第二种情况,调用CreateFile方法来创建文件,该方法会返回该文件的流!就相当于文件是处于被打开的状态!那么如果下次再打开该文件(openFile)那么就会造成重复打开,所以出错!可以改成如下代码:  var  fileStream = isoFile.CreateFile("picture\\myPhoto\\123.jpg");  fileStream.Close();   这样子下次再打开就不会出错了。
第一种情况也是CreateFile,为什么就没错呢?其实第一种情况在第一次运行的时候在openFile时也是出错的,那你肯定会停止运行,看一下代码,觉得没什么错误,然后再次运行。关键就在这里,因为是在独立存储区里创建文件,在第一次运行时123.jpg文件就已经被创建好了,那么你第二次以后的运行就不会进入到if条件里,就不会重新创建,也就不会打开123.jpg,所以第二次以后再运行就不会出错。

 

posted @ 2012-04-15 23:16  仙外仙  阅读(1632)  评论(0编辑  收藏  举报