Como incorporar um arquivo de texto em um assembly .NET?

118

Gostaria de incorporar um arquivo de texto em um assembly para que possa carregar o texto sem ter que lê-lo do disco e para que tudo que preciso esteja contido no exe. (Para que seja mais portátil)

Existe uma maneira de fazer isso? Presumo que algo com os arquivos de recursos?

E se você puder, como você faz isso e como você programaticamente carrega o texto em uma string?

Adam Haile
fonte

Respostas:

147

Clique com o botão direito do mouse no arquivo de projeto e selecione Propriedades.

Na janela que se abre, vá para a guia Recursos e, se houver apenas um link azul no meio da página da guia, clique nele para criar um novo recurso.

insira a descrição da imagem aqui

Então, na barra de ferramentas acima da página da guia, selecione para adicionar um novo arquivo de texto, dê um nome a ele, ele será adicionado ao seu projeto e aberto.

Se você chegou até aqui, então em seu código você pode digitar Resources.TheNameYouGaveTheTextFileHere e você pode acessar seu conteúdo. Observe que a primeira vez que você usa a classe Resources em uma classe, você precisa adicionar uma diretiva using (pressione Ctrl +. Depois de digitar Resources para obter o menu para que o VS faça isso para você).

Se algo não estiver claro sobre a descrição acima, deixe um comentário e irei editá-lo até que esteja completo ou faça sentido :)

Lasse V. Karlsen
fonte
1
Como seria o código da diretiva 'using', estou lutando para fazer isso funcionar. Eu adicionei o solutions.txt como um recurso, mas ele não consegue encontrar Resources.solutions - sinto que estou perdendo a diretiva using.
Spedge
3
Ah-hah, tudo que eu precisava fazer era adicionar um My. para a frente (ou seja, My.Resources.solutions) Simples!
Spedge de
2
Adicionar um recurso gera e inclui Properties\Resources.Designer.cscom namespace YourProjectRootNamespace.Properties, então você tem que usar YourProjectRootNamespace.Properties. ProjectRootNamespaceé definido nas propriedades do seu projeto no VisualStudio.
ilyaigpetrov
1
Se eu adicionar um arquivo de texto dessa maneira e disser que esse arquivo de texto faz parte da minha solução ... se esse arquivo for atualizado e eu reconstruir a montagem, o recurso incorporado também será atualizado? Ou terei de remover / adicionar manualmente o arquivo se eu alguma vez alterá-lo?
Peter Tirrell
3
Os arquivos são empacotados em recursos no momento da compilação, não quando você os adiciona. Você pode alterar livremente o arquivo em qualquer ferramenta que desejar e reconstruir, as alterações farão parte da sua montagem.
Lasse V. Karlsen
38

No Visual Studio 2003, Visual Studio 2005 e possivelmente em versões anteriores (isso também funciona em 2008), você pode incluir o arquivo de texto em seu projeto e, em seguida, no painel 'Propriedades', definir a ação como 'Recurso incorporado'. Em seguida, você pode acessar o arquivo como um fluxo usando Assembly.GetManifestResourceStream(string).

Outras respostas aqui são mais convenientes. Eu incluo isso para ser completo.

Observe que essa abordagem funcionará para incorporar outros tipos de arquivos, como imagens, ícones, sons, etc ...

Drew Noakes
fonte
8
Nota: Use o namespace + nome do arquivo como parâmetro para GetManifestResourceStream (), por exemplo, "MyNamespace.MyTextfile.txt". Você também pode chamar GetManifestResourceNames () para obter uma lista de todos os nomes.
Stiefel
32

Depois de incorporar um arquivo de texto, use esse arquivo em qualquer lugar do código como este ...

global::packageName.Properties.Resources.ThatFileName
Narottam Goyal
fonte
3
Essa é uma abordagem muito melhor porque gerará um erro do compilador se o recurso for removido. Ele também elimina erros de digitação. Obrigado pela postagem.
Ben Gripka
+5. Posso gravá-lo de volta no arquivo dentro do nível C # DLL?
Prajwal Bhat
1
E se eu quiser especificar a ThatFileNamepartir de uma variável?
c00000fd
4

Sim, você está correto - crie um arquivo de recurso. Quando você fizer isso, não precisará "carregar" a string, ela será referenciada como Resource.WhateverStringYouDefined.

Otávio Décio
fonte
2

Aqui está o que funcionou para mim. (Eu precisava ler o conteúdo de um arquivo incorporado em um arquivo de imagem .NET executável.)

Antes de fazer qualquer coisa, inclua seu arquivo em sua solução no Visual Studio. (No meu caso, VS 2017 Community.) Mudei para a pasta, Solution Explorercliquei com o botão direito do mouse Properties, escolhi Add Existing Iteme selecionei o arquivo. (Diga FileName.txt,.) Em seguida, ainda no Solution Explorer, clique com o botão direito do mouse no arquivo incluído, selecione Propertiese escolha Build ActioncomoEmbedded Resource .

Em seguida, use este código para ler seus bytes:

string strResourceName = "FileName.txt";

Assembly asm = Assembly.GetExecutingAssembly();
using( Stream rsrcStream = asm.GetManifestResourceStream(asm.GetName().Name + ".Properties." + strResourceName))
{
    using (StreamReader sRdr = new StreamReader(rsrcStream))
    {
        //For instance, gets it as text
        string strTxt = sRdr.ReadToEnd();
    }
}

Observe que neste caso não é necessário adicionar esse arquivo como recurso conforme foi proposto na resposta aceita .

c00000fd
fonte
1

Aqui está o que eu fiz:

  1. Adicionei meus arquivos (recursos) no Visual Studio clicando com o botão direito do mouse no projeto.
  2. Clique com o botão direito em cada arquivo adicionado e altere o "Tipo de construção" para Recurso incorporado.
  3. Para acessar o recurso:

    uma. Obteve a montagem atual usando a função:GetExecutingAssembly()

    b. O recurso que adicionei foi um arquivo de texto, então li em um fluxo usando GetManifestResourceStream(fileName). Acessei os nomes dos arquivos chamandoGetManifestResourceNames()

    c. Agora use uma StreamReader()classe para ler até o final do arquivo em uma variável se for isso que você deseja.

Pavan
fonte
0

Somando-se a resposta de Pavan, para obter a montagem atual (na seção geral):

Assembly _assembly;

GetManifestResourceStream (fileName) (no código, onde a leitura do recurso é necessária):

try
{
    _assembly = Assembly.GetExecutingAssembly();
    _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("*Namespace*.*FileName*.txt"));
}
catch
{
    Console.WritelLine("Error accessing resource!");
}
Narjis Hasan
fonte