【问题标题】:c# store files content into MemoryStream and read backc# 将文件内容存储到 MemoryStream 并读回
【发布时间】:2021-04-25 14:54:18
【问题描述】:

我正在尝试从特定位置读取所有文件(仅限 xml 类型)。我的目标是将它们存储到 Dictionary 字典中。调用 StreamAll() 方法后,我想调用所需的文件 StreamReportFiles.dict[10] 来接收正确版本的 xml 文件。

这是正确的方法吗?以及如何将 StreamReportFiles.dict[10] 转换回字符串或 XmlDocument,同时将其转换为 bytes[]?

class StreamReportFiles
{
public static Dictionary<int, MemoryStream> dict;

    public static void StreamAll()
    {
        DirectoryInfo dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"c:\Templates\"));
        FileInfo[] Files = dir.GetFiles("*.xml");
        dict= new Dictionary<int, MemoryStream>();


        if (Files.Length > 0)
        {
            long len;
            MemoryStream ms;

            foreach (FileInfo fileInfo in Files)
            {

                using (FileStream file = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read))
                {
                    ms = new MemoryStream();
                    byte[] bytes = new byte[file.Length];

                    ms.Write(bytes, 0, (int)file.Length);
                    len = file.Length / 1024;

                    RdlcDictStream.Add(Convert.ToInt32(fileInfo.Name.Substring(0, fileInfo.Name.Length - fileInfo.Extension.Length)), ms);
                }
                Console.WriteLine($"File {fileInfo.Name}  {len} kB size added to MemoryStream");
            }
            
        }

    }

}

}

【问题讨论】:

    标签: c# stream console-application


    【解决方案1】:

    警告:读取未定义总大小的未定义文件数量可能会导致OutOfMemoryException。小心这个。

    顺便说一句,如果要将数据存储在内存中,最好将其存储在数组中。

    public static Dictionary<int, byte[]> Data { get; private set; }
    
    public static void LoadAllTemplates()
    {
        Data = new Dictionary<int, byte[]>();
        DirectoryInfo dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Templates"));
    
        foreach (FileInfo fileInfo in dir.GetFiles("*.xml"))
        {
            if (int.TryParse(fileInfo.Name.Remove(fileInfo.Name.Length - fileInfo.Extension.Length), out int key))
            {
                Data[key] = File.ReadAllBytes(fileInfo.FullName);
                Console.WriteLine($"File {fileInfo.Name} {fileInfo.Length / 1024} kB size added to Data");
            }
            else
                Console.WriteLine($"Failed to parse filename {fileInfo.Name}");
        }
    }
    

    用法可以

    StreamReportFiles.LoadAllTemplates();
    Console.WriteLine(Encoding.UTF8.GetString(StreamReportFiles.Data[10])); 
    

    【讨论】:

    • 非常感谢伙计!!!这是适合我需要的解决方案!为什么在 MemoryStream 上使用数组更好?还要感谢您的提醒,但不用担心 - 我期待少量的 xml 文件,最大大小约为 1mb。但是每个 xml 文件的读取时间很重要——所以为了避免磁盘读取,我决定最好将它们保存在内存中(可能在 1 个月内这些文件可能会打开 100 万次)。
    • @zawier 数组在将数据保存在内存中时更易于处理且效率更高。要管理MemoryStream,您需要在每次读取后将其Position 重置为0。另一方面,您可以将它转换为.ToArray(),它会复制内容(目前内存消耗翻倍),而在这种情况下可以直接使用数组。顺便说一句,MS 无论如何都将数据保存在 undelying byte[] 数组中,只是将其包装起来。
    【解决方案2】:

    据我了解,您希望将具有 byte[] 格式的 xml 数据的 MemoryStream 转换回 XML 字符串。

    为此,您可以使用 System.Text.Encoding.UTF8.GetString(StreamReportFiles.dict[0])

    【讨论】:

    • System.Data.Encoding -> 找不到这样的库。不幸的是,我正在使用 Framework 4.7。回答您的问题:我想将所有 xml 文档保存到 Memory Stream 中(以避免在此之后从磁盘打开它们数百次至关重要),然后存储在我想要的内存中进行一些修改..这是短篇小说;)
    • 使用当前解决方案我得到错误 CS1503 Argument 1: cannot convert from 'System.IO.MemoryStream' to 'byte[]'
    • 你可以这样写: byte[] data = new byte[ms.Length]; ms.Read(data, 0, ms.Length); System.Text.Encoding.GetString(data);
    • 1) StreamReportFiles.dict[10].Read(data, 0, StreamReportFiles.dict[10].Length)-> 错误 CS1503 参数 3:无法从 'long' 转换为 'int' ; 2) Console.WriteLine(System.Text.Encoding.GetString(data)); -> 错误 CS0120 非静态字段、方法或属性“Encoding.GetString(byte[])”需要对象引用
    猜你喜欢
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多