如何读取可移植类库中的资源文件?

Mar*_*tin 22 .net c# embedded-resource

我有一个可移植的库,我用于Windows Phone应用程序.在同一个可移植库中,我有几个内容文件(Build Action = Content).

DataReader在Portable Library中创建了一个类,它应该向我返回一个流到内容文件.然而,下面的代码我一直取回nullGetManifestResourceStream.我究竟做错了什么?

public class DataReader
{
    public static Stream GetStream(string code)
    {
        string path = string.Format("./data/code-{0}.dat", code);
        return Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*ott 36

你的道路是错的.您正在使用斜杠,但在嵌入式清单资源名称中,斜杠在构建期间转换为句点.此外,根据您的PCL目标平台,您甚至可能无法打电话Assembly.GetExecutingAssembly().

这是你可以做的:

var assembly = typeof(AnyTypeInYourAssembly).GetTypeInfo().Assembly;

// Use this help aid to figure out what the actual manifest resource name is.
string[] resources = assembly.GetManifestResourceNames();

// Once you figure out the name, pass it in as the argument here.
Stream stream = assembly.GetManifestResourceStream("Some.Path.AndFileName.Ext");
Run Code Online (Sandbox Code Playgroud)

  • @Dpedrinha:它可以替代你装配中的任何类型.选择一个. (2认同)

Mil*_*ith 9

来自http://social.msdn.microsoft.com/Forums/windowsapps/en-US/386eb3b2-e98e-4bbc-985f-fc143db6ee36/read-local-file-in-portable-library#386eb3b2-e98e-4bbc-985f -fc143db6ee36

无法在Windows应用商店应用和Windows Phone 8应用之间轻松进行文件访问.您必须使用特定于平台的代码,才能打开文件并获取流.然后,您可以将流传递到PCL.

如果使用内容构建操作构建它,则XML不在DLL内部.它在文件系统上,并且没有办法从PCL内部获取它.这就是为什么所有答案都将构建操作设置为嵌入式资源的原因.它将文件放在里面MyPCL.DLL\Path\To\Content.xml.

但是,如果将构建操作设置为" 内容"并将复制类型设置为" 复制"(如果较新),则会将文件放在与可执行文件相同的目录中.

Solution Explorer,Properties和Windows Explorer

因此,我们可以在我们的PCL中放置一个用于读取文件的界面.在启动我们的非便携代码时,我们将一个实现注入PCL.

namespace TestPCLContent
{
    public interface IContentProvider
    {
        string LoadContent(string relativePath);
    }
}

namespace TestPCLContent
{
    public class TestPCLContent
    {
        private IContentProvider _ContentProvider;
        public IContentProvider ContentProvider
        {
            get
            {
                return _ContentProvider;
            }
            set
            {
                _ContentProvider = value;
            }
        }

        public string GetContent()
        {
            return _ContentProvider.LoadContent(@"Content\buildcontent.xml");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

既然上面已经定义了PCL,我们可以在不可移植的代码中创建我们的接口实现(下面):

namespace WPFBuildContentTest
{
    class ContentProviderImplementation : IContentProvider
    {
        private static Assembly _CurrentAssembly;

        private Assembly CurrentAssembly
        {
            get
            {
                if (_CurrentAssembly == null)
                {
                    _CurrentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
                }

                return _CurrentAssembly;
            }
        }

        public string LoadContent(string relativePath)
        {
            string localXMLUrl = Path.Combine(Path.GetDirectoryName(CurrentAssembly.GetName().CodeBase), relativePath);
            return File.ReadAllText(new Uri(localXMLUrl).LocalPath);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序启动时,我们注入实现,并演示加载内容.

namespace WPFBuildContentTest
{
    //App entrance point. In this case, a WPF Window
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ContentProviderImplementation cpi = new ContentProviderImplementation();

            TestPCLContent.TestPCLContent tpc = new TestPCLContent.TestPCLContent();
            tpc.ContentProvider = cpi; //injection

            string content = tpc.GetContent(); //loading
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:为简单起见,我保留了字符串而不是Streams.


Dam*_*ith 0

如果您已将文件添加为资源,请检查您的.Designer.cs,每个资源都会有一个属性。您可以从中访问。

这是 dat 文件资源的示例自动生成属性

   internal static byte[] MyDatFile {
        get {
            object obj = ResourceManager.GetObject("MyDatFile", resourceCulture);
            return ((byte[])(obj));
        }
Run Code Online (Sandbox Code Playgroud)

您可以将 dat 文件读取为

    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
    var str = enc.GetString(Resource1.MyDatFile);
Run Code Online (Sandbox Code Playgroud)