你的位置:首页 > 操作系统

[操作系统]Windows 10开发基础——文件、文件夹和库(一)


主要内容:

     1.枚举查询文件和文件夹

     2.文本文件读写的三种方法——创建写入和读取文件

     3.获得文件的属性

 

枚举查询文件和文件夹

先了解一下文件查询的几个方法:

StorageFolder.GetFilesAsync: 获取当前文件夹中的所有文件,返回一个 IReadOnlyList<StorageFile>集合

         IReadOnlyList<StorageFile> fileList =await picturesFolder.GetFilesAsync();

StorageFolder.GetFolersAsync:获取当前文件夹中的所有子文件夹,返回一个IReadOnlyList<StorageFolder>集合

        IReadOnlyList<StorageFolder> folderList =await picturesFolder.GetFoldersAsync();

 StorageFolder.GetItemsAsync:获取当前文件夹中的所有文件和子文件夹,返回一个IReadOnlyList<IStorageItem>集合

        ReadOnlyList<IStorageItem> itemsList =await picturesFolder.GetItemsAsync();

        e.g:

       StorageFolder picturesFolder = KnownFolders.PicturesLibrary;

       StringBuilder outputText = new StringBuilder();

       IReadOnlyList<IStorageItem> itemsList = await picturesFolder.GetItemsAsync();//获取当前文件夹中的所有文件和子文件夹
       foreach (var item in itemsList)
       {
             if (item is StorageFolder)
            {
                  outputText.Append(item.Name + " folder\n");

             }
             else
            {
                  outputText.Append(item.Name + "\n");
            }
       }

还要注意一下查询某个位置中的文件并枚举匹配的文件(CommonFolderQuery可取的枚举值很多,转到定义了解一下咯)

StorageFolder picturesFolder = KnownFolders.PicturesLibrary;

StorageFolderQueryResult queryResult = picturesFolder.CreateFolderQuery(CommonFolderQuery.GroupByMonth);//这一行是主要代码,将同一月份的文件归类到一个文件夹
IReadOnlyList<StorageFolder> folderList = await queryResult.GetFoldersAsync();//检索结果集中的文件夹列表

StringBuilder outputText = new StringBuilder();
foreach (StorageFolder folder in folderList)
{
     IReadOnlyList<StorageFile> fileList = await folder.GetFilesAsync();

     outputText.AppendLine(folder.Name + " (" + fileList.Count + ")");//folder.Name的值类似于:2014年12月
     foreach (StorageFile file in fileList)
     {
        outputText.AppendLine(" " + file.Name);
     }
}

 

 

然后我们再来看一个实例:

查询出图片库根目录中的所有图片,然后将图片文件名显示在一个列表中,点击列表的某一项,Image显示对应的图片。

图片库对应于电脑中的下图:

 

1.在Package.appxmanifest中的“功能”节点中选中“图片库”

2.界面布局

   一个按钮,一个ListView,一个Image

 1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 2     <Grid.RowDefinitions> 3       <RowDefinition Height="auto"></RowDefinition> 4       <RowDefinition Height="*"></RowDefinition> 5     </Grid.RowDefinitions> 6     <Button x:Name="button" Content="点击查看图片库" HorizontalAlignment="Center" Margin="0,10,0,10" VerticalAlignment="Top" Click="button_Click" Width="161"/> 7     <Grid Grid.Row="1"> 8       <Grid.ColumnDefinitions> 9         <ColumnDefinition></ColumnDefinition>10         <ColumnDefinition></ColumnDefinition>11       </Grid.ColumnDefinitions>12       <ListView SelectionMode="Single" x:Name="lv_file" Margin="10" Grid.Column="0" IsEnabled="True" SelectionChanged="lv_file_SelectionChanged" >13         <ListView.ItemTemplate>14           <DataTemplate>15             <TextBlock Text="{Binding}" FontSize="20" Margin="0,5,0,0" Foreground="Black"></TextBlock>16           </DataTemplate>17         </ListView.ItemTemplate>18       </ListView>19       <Image x:Name="img" Grid.Column="1" Source="Assets/Images/nokiagood2.jpg"></Image>20     </Grid>21   </Grid>

3.后台代码

  loadData方法用来获取图片库中的图片,并将文件名绑定的ListView控件上,我们可以在页面的构造函数里面调用它,在应用程序启动之后就显示列表数据。

  在显示图片时用到了WriteableBitmap,它用来创建可显示和更新的位图对象,通过将图片文件写入流(IRandomAccessStream)中,然后从流中读取图形数据并保存到位图中来显示图片。

  GetFileAsync()方法根据传入的string来获取指定的文件

 1  private async void loadData() 2     {//获取图片库中的图片,并将文件名绑定的ListView控件上 3  4       picturesFolder = KnownFolders.PicturesLibrary;//获取图片库 5       List<string> filestrlists = new List<string>(); 6       IReadOnlyList<StorageFile> fileList =await picturesFolder.GetFilesAsync();  //获取当前文件夹中的所有文件 7       foreach (StorageFile file in fileList) 8       { 9         filestrlists.Add(file.Name);10       }11       lv_file.ItemsSource = filestrlists;12     }13 14     private void button_Click(object sender, RoutedEventArgs e)15     {16       loadData();17     }18 19     private async void lv_file_SelectionChanged(object sender, SelectionChangedEventArgs e)20     {//ListView的选中事件,选择某一项时显示对应得图片21 22       WriteableBitmap writeableBitmap = new WriteableBitmap(500,500);23       string filename = lv_file?.SelectedItem as string;24 25       if (filename != null)26       {27         StorageFile file = await picturesFolder?.GetFileAsync(filename);28         IRandomAccessStream stream = await file?.OpenAsync(FileAccessMode.Read);29         await writeableBitmap.SetSourceAsync(stream);30         img.Source = writeableBitmap;31       }32     }

4.运行测试。

   

 

文本文件读写的三种方法——创建写入和读取文件

方法一:使用FileIO类WriteTextAsync和ReadTextAsync方法

await FileIO.WriteTextAsync(sampleFile,tb_txt.Text.Trim());//写

string text = await FileIO.ReadTextAsync(sampleFile);      //读

方法二:使用缓冲区(Buffer)

    写:

     var buffer = CryptographicBuffer.ConvertStringToBinary(tb_txt.Text.Trim(), BinaryStringEncoding.Utf8);

     await FileIO.WriteBufferAsync(sampleFile, buffer); 

   读:

     var buffer = await FileIO.ReadBufferAsync(sampleFile);

     using (var dataReader =DataReader.FromBuffer(buffer))

     {

        string text = dataReader.ReadString(buffer.Length);

     }

方法三:使用流(Stream)

      写:

            var stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);

            using (var outputStream = stream.GetOutputStreamAt(0))

            {

                using (var dataWriter = new DataWriter(outputStream))

                {

                    dataWriter.WriteString(tb_txt.Text.Trim());

                    await dataWriter.StoreAsync();

                    await outputStream.FlushAsync();

                }

            }

        stream.Dispose();

      读:

           var stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);

            ulong size = stream.Size;

            using (var inputStream = stream.GetInputStreamAt(0))

            {

                using (var dataReader = new DataReader(inputStream))

                {

                    uint numBytesLoaded = await dataReader.LoadAsync((uint)size);

                    string text = dataReader.ReadString(numBytesLoaded);

             }

 

接下来是常规演示:在文本框里输入文本,然后点击create按钮创建并写入文件,然后get按钮读出文件中的内容。

界面很简单,直接上图:

代码也容易理解,我就直接贴(注意一些变量的定义是可以提到方法外面的,为了演示,我就都写在方法里面了,实际使用的时候根据情况处理就好了)。

对应于方法一:

    private async void btn_createFile_Click(object sender, RoutedEventArgs e)    {      // 创建一个文件(sample.txt); 如果存在就替换.      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile =await folder.CreateFileAsync("sample.txt",CreationCollisionOption.ReplaceExisting);      await FileIO.WriteTextAsync(sampleFile,tb_txt.Text.Trim());    }    private async void btn_getFile_Click(object sender, RoutedEventArgs e)    {      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile =await folder.GetFileAsync("sample.txt");      string text = await FileIO.ReadTextAsync(sampleFile);      showmsg(text);    }    private async void showmsg(string content)    {      MessageDialog msg = new MessageDialog(content, "info");      await msg.ShowAsync();    }

对应于方法二:

    private async void btn_cerateFileBuffer_Click(object sender, RoutedEventArgs e)    {      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile = await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);      var buffer = CryptographicBuffer.ConvertStringToBinary(tb_txt.Text.Trim(), BinaryStringEncoding.Utf8);           await FileIO.WriteBufferAsync(sampleFile, buffer);    }    private async void btn_getFileBuffer_Click(object sender, RoutedEventArgs e)    {      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile = await folder.GetFileAsync("sample.txt");      var buffer = await FileIO.ReadBufferAsync(sampleFile);      string text;      using (var dataReader =DataReader.FromBuffer(buffer))      {        text = dataReader.ReadString(buffer.Length);      }      showmsg(text);    }

对应于方法三:

  private async void btn_createFileStream_Click(object sender, RoutedEventArgs e)    {      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile =await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);      var stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);      using (var outputStream = stream.GetOutputStreamAt(0))      {        using (var dataWriter = new DataWriter(outputStream))        {          dataWriter.WriteString(tb_txt.Text.Trim());          await dataWriter.StoreAsync();          await outputStream.FlushAsync();        }      }      stream.Dispose();     }    private async void btn_getFileStream_Click(object sender, RoutedEventArgs e)    {      StorageFolder folder = ApplicationData.Current.LocalFolder;      StorageFile sampleFile = await folder.GetFileAsync("sample.txt");      var stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);      ulong size = stream.Size;      using (var inputStream = stream.GetInputStreamAt(0))      {        string text;        using (var dataReader = new DataReader(inputStream))        {          uint numBytesLoaded = await dataReader.LoadAsync((uint)size);          text = dataReader.ReadString(numBytesLoaded);        }        showmsg(text);      }    }

然后我们再来看一个实例:

将部分程序界面截图保存至应用程序存储,然后进行读取。还将演示如何保存至图片库。

1.涉及到操作图片库,首先也要去Package.appxmanifest中的“功能”节点中选中“图片库”。(以后不再赘述)

2.界面布局

  注意grid和cgrid都是我们要截图保存的UI元素,都要给它们一个Background。(你可以试试,不给是什么情况)

  <Grid x:Name="grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">    <Grid.RowDefinitions>      <RowDefinition Height="*"></RowDefinition>      <RowDefinition Height="*"></RowDefinition>    </Grid.RowDefinitions>    <Grid Margin="10" x:Name="cgrid"  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">      <Button x:Name="btn_createImg" Content="create a picture file" HorizontalAlignment="Left" Margin="12,33,0,0" VerticalAlignment="Top" Click="btn_createImg_Click"/>      <Button x:Name="btn_getImg" Content="get a picture file" HorizontalAlignment="Left" Margin="206,33,0,0" VerticalAlignment="Top" Click="btn_getImg_Click"/>      <Image x:Name="img_original" HorizontalAlignment="Left" Margin="12,117,0,0" Source="Assets/Images/nokiagood2.jpg" Stretch="UniformToFill" VerticalAlignment="Top" Width="338"/>      <Button x:Name="btn_save" Content="save to photos" HorizontalAlignment="Left" Margin="12,80,0,0" VerticalAlignment="Top" Width="128" Click="btn_save_Click"/>    </Grid>    <Image Grid.Row="1" x:Name="img_create" HorizontalAlignment="Left" Height="217" Margin="12,20,0,0" Stretch="UniformToFill" VerticalAlignment="Top" Width="338"/>  </Grid>

3.后台代码

创建图片文件并保存至应用程序存储中。RenderTargetBitmap、BitmapEncoder类需要重点理解一下。

  private async void btn_createImg_Click(object sender, RoutedEventArgs e)    {      renderTargetBitmap = new RenderTargetBitmap();//RenderTargetBitmap类可以将可视化对象转换为位图      await renderTargetBitmap.RenderAsync(cgrid);      var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();      var folder = ApplicationData.Current.LocalFolder;      var file = await folder.CreateFileAsync("screenshot.png",CreationCollisionOption.ReplaceExisting);      using (var stream=await file.OpenAsync(FileAccessMode.ReadWrite))      {        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);//BitmapEncoder类包含创建、编辑和保存图像的各种方法        encoder.SetPixelData(BitmapPixelFormat.Bgra8,                         BitmapAlphaMode.Ignore,                         (uint)renderTargetBitmap.PixelWidth,                        (uint)renderTargetBitmap.PixelHeight,                        DisplayInformation.GetForCurrentView().LogicalDpi,                        DisplayInformation.GetForCurrentView().LogicalDpi,                        pixelBuffer.ToArray());      //设置图像有关帧的像素数据        await encoder.FlushAsync();//提交和刷新图像数据      }    }

 

从应用程序中读取显示图片

  private async void btn_getImg_Click(object sender, RoutedEventArgs e)    {      //方法一:类似于实例一中的方法来展示图片      WriteableBitmap writeableBitmap = new WriteableBitmap(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight);      var folder = ApplicationData.Current.LocalFolder;      var file = await folder.GetFileAsync("screenshot.png");      IRandomAccessStream stream = await file?.OpenAsync(FileAccessMode.Read);      await writeableBitmap.SetSourceAsync(stream);      img_create.Source = writeableBitmap;      //方法二:通过应用文件的Uri方案来展示图片      //BitmapImage bitmapImage = new BitmapImage(new Uri("ms-appdata:///local/screenshot.png", UriKind.Absolute));      //img_create.Source = bitmapImage;    }

 

将图片保存至图片库。

  private async void btn_save_Click(object sender, RoutedEventArgs e)    {      WriteableBitmap writeableBitmap = new WriteableBitmap(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight);      var folder = ApplicationData.Current.LocalFolder;      var sourcefile = await folder.GetFileAsync("screenshot.png");//获取图片screenshot.png      StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("screenshot.png",CreationCollisionOption.ReplaceExisting);//在图片库中的CameraRoll文件夹中创建文件      using (var sourceStream = await sourcefile.OpenReadAsync())      {        using (var sourceInputStream = sourceStream.GetInputStreamAt(0))        {          using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))          {            using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))            {              await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);//复制源流到目标流            }          }        }      }    }

4.运行测试。

 

 

获得文件的属性

(msdn: https://msdn.microsoft.com/zh-cn/library/windows/apps/mt186454.aspx )

获取文件的顶级属性(这些属性包括文件属性、内容类型、创建日期、显示名称和文件类型等。)

              StringBuilder fileProperties = new StringBuilder();
              fileProperties.AppendLine("File name: " + file.Name);
              fileProperties.AppendLine("File type: " + file.FileType);

获取文件的基本属性

多数基本属性都是通过先调用StorageFile.GetBasicPropertiesAsync()方法获得的。此方法会返回一个BasicProperties对象,该对象将定义项(文件或文件夹)的大小属性,以及上次修改项的时间。

              BasicProperties basicProperties = await file.GetBasicPropertiesAsync();

              string fileSize = string.Format("{0:n0}", basicProperties.Size);
              fileProperties.AppendLine("File size: " + fileSize + " bytes");
              fileProperties.AppendLine("Date modified: " + basicProperties.DateModified);

获取文件的扩展属性

扩展属性只能通过以下方法获得:将代表将要检索的属性名称的 String 对象的 IEnumerable 集合传递到BasicProperties.RetrievePropertiesAsync 方法。之后此方法会返回一个 IDictionary 集合。然后可以按名称或通过索引从这个集合中检索每个扩展属性。     

  const string dateAccessedProperty = "System.DateAccessed";      const string fileOwnerProperty = "System.FileOwner";      var folder = KnownFolders.PicturesLibrary;      var query = folder.CreateFileQuery();      var files = await query.GetFilesAsync();      foreach (StorageFile file in files)      {        StringBuilder fileProperties = new StringBuilder();        var propertyNames = new List<string>();        propertyNames.Add(dateAccessedProperty);        propertyNames.Add(fileOwnerProperty);        IDictionary<string, object> extraProperties = await file.Properties.RetrievePropertiesAsync(propertyNames);            var propValue = extraProperties[dateAccessedProperty];        if (propValue != null)        {          fileProperties.AppendLine("Date accessed: " + propValue);        }        propValue = extraProperties[fileOwnerProperty];        if (propValue != null)        {          fileProperties.AppendLine("File owner: " + propValue);        }

太晚了,这个不准备实例了。睡觉!