• 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 ");

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

    还要注意一下查询某个位置中的文件并枚举匹配的文件(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.后台代码

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

       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);
                    }

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

  • 相关阅读:
    uni.navigateTo 无法跳转到页面
    微信小程序 navigateTo 只能使用几次 无效后 怎么处理的?
    Vue中computed和watch的区别
    vue 动态添加样式的方式
    浏览器数据库IndexedDB介绍
    Gitlab CI/CD 之 Gitlab Runner Docker Executor 缓存问题
    Gitlab CI/CD 之 Gitlab-Runner
    .neter 的 java 学习之路
    Gitlab 迁移后 runner 访问报错的问题
    .neter 的 java 学习之路
  • 原文地址:https://www.cnblogs.com/czhwust/p/Win10_file.html
Copyright © 2020-2023  润新知