임베디드 리소스 텍스트 파일 읽는 방법
포함 된 리소스 (텍스트 파일)를 어떻게 읽고 StreamReader
문자열로 반환합니까? 내 현재 스크립트는 사용자가 포함되지 않은 텍스트 파일에서 텍스트를 찾고 바꿀 수있는 Windows 양식 및 텍스트 상자를 사용합니다.
private void button1_Click(object sender, EventArgs e)
{
StringCollection strValuesToSearch = new StringCollection();
strValuesToSearch.Add("Apple");
string stringToReplace;
stringToReplace = textBox1.Text;
StreamReader FileReader = new StreamReader(@"C:\MyFile.txt");
string FileContents;
FileContents = FileReader.ReadToEnd();
FileReader.Close();
foreach (string s in strValuesToSearch)
{
if (FileContents.Contains(s))
FileContents = FileContents.Replace(s, stringToReplace);
}
StreamWriter FileWriter = new StreamWriter(@"MyFile.txt");
FileWriter.Write(FileContents);
FileWriter.Close();
}
Assembly.GetManifestResourceStream
방법을 사용할 수 있습니다 .
다음 용도를 추가하십시오.
using System.IO; using System.Reflection;
관련 파일의 속성 설정 : 값이있는
매개 변수Build Action
Embedded Resource
다음 코드를 사용하십시오.
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyCompany.MyProduct.MyFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
resourceName
에 포함 된 리소스 중 하나의 이름입니다 assembly
. 라는 이름의 텍스트 파일을 포함 할 경우 예를 들어, "MyFile.txt"
기본 네임 스페이스 프로젝트의 루트에 위치 "MyCompany.MyProduct"
하고 resourceName
있습니다 "MyCompany.MyProduct.MyFile.txt"
. Assembly.GetManifestResourceNames
Method를 사용하여 어셈블리의 모든 리소스 목록을 가져올 수 있습니다 .
resourceName
파일 이름에서만 (네임 스페이스 항목을 전달하여) 가져 오는 것에 대해 생각할 필요가 없습니다 .
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("YourFileName.txt"));
별도의 두 가지 방법을 사용하여 파일을 리소스로 추가 할 수 있습니다.
파일에 액세스하는 데 필요한 C # 코드 는 처음에 파일을 추가하는 데 사용 된 방법에 따라 다릅니다.
방법 1 : 기존 파일 추가, 속성 설정 Embedded Resource
프로젝트에 파일을 추가 한 다음 유형을 Embedded Resource
.
참고 :이 방법을 사용하여 파일을 추가 하면를 사용하여 파일 GetManifestResourceStream
에 액세스 할 수 있습니다 ( @dtb의 답변 참조 ).
방법 2 : 파일 추가 Resources.resx
위 열고 Resources.resx
, 설정을 파일을 추가 드롭 다운 상자를 사용하여 파일을 Access Modifier
로 public
.
참고 :이 방법을 사용하여 파일을 추가 하면를 사용하여 파일 Properties.Resources
에 액세스 할 수 있습니다 ( @Night Walker의 답변 참조 ).
기본적으로 System.Reflection
현재 어셈블리에 대한 참조를 가져 오는 데 사용 합니다. 그런 다음 GetManifestResourceStream()
.
예를 들어 내가 게시 한 페이지에서 :
참고 : using System.Reflection;
이 기능 을 사용 하려면 추가해야합니다.
Assembly _assembly;
StreamReader _textStreamReader;
try
{
_assembly = Assembly.GetExecutingAssembly();
_textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
}
catch
{
MessageBox.Show("Error accessing resources!");
}
Visual Studio에서는 프로젝트 속성의 리소스 탭 (이 예에서는 "분석")을 통해 파일 리소스에 대한 액세스를 직접 포함 할 수 있습니다.
결과 파일은 다음을 통해 바이트 배열로 액세스 할 수 있습니다.
byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;
스트림으로 필요하면 ( https://stackoverflow.com/a/4736185/432976에서 )
Stream stream = new MemoryStream(jsonSecrets)
리소스에 파일을 추가 할 때 다음과 같이 만들 수있는 것보다 해당 액세스 수정자를 공용으로 선택해야합니다.
byte[] clistAsByteArray = Properties.Resources.CLIST01;
CLIST01은 임베드 된 파일의 이름입니다.
실제로 resources.Designer.cs로 이동하여 getter의 이름이 무엇인지 확인할 수 있습니다.
나는 그것이 오래된 스레드라는 것을 알고 있지만 이것이 나를 위해 일한 것입니다.
- 프로젝트 리소스에 텍스트 파일 추가
- Andrew Hill이 위에서 보여준 것처럼 access modifier를 public으로 설정합니다.
다음과 같은 텍스트를 읽으십시오.
textBox1 = new TextBox(); textBox1.Text = Properties.Resources.SomeText;
리소스에 추가 한 텍스트 : 'SomeText.txt'
추가 예 : Testfile.sql 프로젝트 메뉴-> 속성-> 리소스-> 기존 파일 추가
string queryFromResourceFile = Properties.Resources.Testfile.ToString();
이 단순화 된 버전의 @dtb 답변을 사용할 수도 있습니다.
public string GetEmbeddedResource(string ns, string res)
{
using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", ns, res))))
{
return reader.ReadToEnd();
}
}
방금 배운 것은 파일에 "."가 있으면 안된다는 것입니다. (점) 파일 이름에.
Templates.plainEmailBodyTemplate-en.txt-> 작동 !!!
Templates.plainEmailBodyTemplate.en.txt-> GetManifestResourceStream ()을 통해 작동하지 않습니다.
아마도 프레임 워크가 네임 스페이스 대 파일 이름을 혼동하기 때문일 것입니다.
모든 힘을 합쳐서이 도우미 클래스를 사용하여 어셈블리와 네임 스페이스에서 리소스를 일반적인 방식으로 읽습니다.
public class ResourceReader
{
public static IEnumerable<string> FindEmbededResources<TAssembly>(Func<string, bool> predicate)
{
if (predicate == null) throw new ArgumentNullException(nameof(predicate));
return
GetEmbededResourceNames<TAssembly>()
.Where(predicate)
.Select(name => ReadEmbededResource(typeof(TAssembly), name))
.Where(x => !string.IsNullOrEmpty(x));
}
public static IEnumerable<string> GetEmbededResourceNames<TAssembly>()
{
var assembly = Assembly.GetAssembly(typeof(TAssembly));
return assembly.GetManifestResourceNames();
}
public static string ReadEmbededResource<TAssembly, TNamespace>(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
return ReadEmbededResource(typeof(TAssembly), typeof(TNamespace), name);
}
public static string ReadEmbededResource(Type assemblyType, Type namespaceType, string name)
{
if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
if (namespaceType == null) throw new ArgumentNullException(nameof(namespaceType));
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
return ReadEmbededResource(assemblyType, $"{namespaceType.Namespace}.{name}");
}
public static string ReadEmbededResource(Type assemblyType, string name)
{
if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
var assembly = Assembly.GetAssembly(assemblyType);
using (var resourceStream = assembly.GetManifestResourceStream(name))
{
if (resourceStream == null) return null;
using (var streamReader = new StreamReader(resourceStream))
{
return streamReader.ReadToEnd();
}
}
}
}
포함 된 리소스 텍스트 파일 사용을 읽었습니다.
/// <summary>
/// Converts to generic list a byte array
/// </summary>
/// <param name="content">byte array (embedded resource)</param>
/// <returns>generic list of strings</returns>
private List<string> GetLines(byte[] content)
{
string s = Encoding.Default.GetString(content, 0, content.Length - 1);
return new List<string>(s.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
}
견본:
var template = GetLines(Properties.Resources.LasTemplate /* resource name */);
template.ForEach(ln =>
{
Debug.WriteLine(ln);
});
나는 이것이 오래 되었다는 것을 알고 있지만 NETMF (.Net MicroFramework)에 대해 지적하고 싶었습니다. 쉽게 할 수 있습니다.
string response = Resources.GetString(Resources.StringResources.MyFileName);
이후 NETMF는 없습니다GetManifestResourceStream
여기에 게시 된 모든 솔루션을 읽은 후. 이것이 내가 해결 한 방법입니다.
// How to embedded a "Text file" inside of a C# project
// and read it as a resource from c# code:
//
// (1) Add Text File to Project. example: 'myfile.txt'
//
// (2) Change Text File Properties:
// Build-action: EmbeddedResource
// Logical-name: myfile.txt
// (note only 1 dot permitted in filename)
//
// (3) from c# get the string for the entire embedded file as follows:
//
// string myfile = GetEmbeddedResourceFile("myfile.txt");
public static string GetEmbeddedResourceFile(string filename) {
var a = System.Reflection.Assembly.GetExecutingAssembly();
using (var s = a.GetManifestResourceStream(filename))
using (var r = new System.IO.StreamReader(s))
{
string result = r.ReadToEnd();
return result;
}
return "";
}
문자열에 항상 네임 스페이스와 폴더를 포함해야한다는 점에 짜증이났습니다. 임베디드 리소스에 대한 액세스를 단순화하고 싶었습니다. 이것이 제가이 작은 수업을 작성한 이유입니다. 자유롭게 사용하고 개선하십시오!
용법:
using(Stream stream = EmbeddedResources.ExecutingResources.GetStream("filename.txt"))
{
//...
}
수업:
public class EmbeddedResources
{
private static readonly Lazy<EmbeddedResources> _callingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetCallingAssembly()));
private static readonly Lazy<EmbeddedResources> _entryResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetEntryAssembly()));
private static readonly Lazy<EmbeddedResources> _executingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetExecutingAssembly()));
private readonly Assembly _assembly;
private readonly string[] _resources;
public EmbeddedResources(Assembly assembly)
{
_assembly = assembly;
_resources = assembly.GetManifestResourceNames();
}
public static EmbeddedResources CallingResources => _callingResources.Value;
public static EmbeddedResources EntryResources => _entryResources.Value;
public static EmbeddedResources ExecutingResources => _executingResources.Value;
public Stream GetStream(string resName) => _assembly.GetManifestResourceStream(_resources.Single(s => s.Contains(resName)));
}
대답은 매우 간단합니다. resources.resx에서 직접 파일을 추가 한 경우 간단하게 수행하십시오.
string textInResourceFile = fileNameSpace.Properties.Resources.fileName;
해당 코드 줄을 사용하여 파일의 텍스트를 파일에서 직접 읽어 문자열 변수에 넣습니다.
public class AssemblyTextFileReader
{
private readonly Assembly _assembly;
public AssemblyTextFileReader(Assembly assembly)
{
_assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
}
public async Task<string> ReadFileAsync(string fileName)
{
var resourceName = _assembly.GetManifestResourceName(fileName);
using (var stream = _assembly.GetManifestResourceStream(resourceName))
{
using (var reader = new StreamReader(stream))
{
return await reader.ReadToEndAsync();
}
}
}
}
public static class AssemblyExtensions
{
public static string GetManifestResourceName(this Assembly assembly, string fileName)
{
string name = assembly.GetManifestResourceNames().SingleOrDefault(n => n.EndsWith(fileName, StringComparison.InvariantCultureIgnoreCase));
if (string.IsNullOrEmpty(name))
{
throw new FileNotFoundException($"Embedded file '{fileName}' could not be found in assembly '{assembly.FullName}'.", fileName);
}
return name;
}
}
일부 VS .NET 프로젝트 유형은 .NET (.resx) 파일을 자동 생성하지 않습니다. 다음 단계는 프로젝트에 리소스 파일을 추가합니다.
- 프로젝트 노드를 마우스 오른쪽 버튼으로 클릭하고 추가 / 새 항목을 선택하고 리소스 파일로 스크롤합니다. 이름 상자에서 적절한 이름 (예 : Resources)을 선택하고 추가 버튼을 클릭합니다.
- 리소스 파일 Resources.resx가 프로젝트에 추가되고 솔루션 탐색기에서 노드로 표시 될 수 있습니다.
- 실제로 두 개의 파일이 생성되고 자동 생성 된 C # 클래스 Resources.Designer.cs도 있습니다. 편집하지 마십시오. VS에서 관리합니다. 파일에는
Resources
.
이제 텍스트 파일을 리소스 (예 : xml 파일)로 추가 할 수 있습니다.
- Resources.resx를 두 번 클릭합니다. 리소스 추가> 기존 파일 추가를 선택하고 포함 할 파일로 스크롤합니다. Access Modify에 대해 기본값 내부를 그대로 둡니다.
- 아이콘은 새 리소스 항목을 나타냅니다. 선택하면 속성 창에 속성이 표시됩니다. xml 파일의 경우 인코딩 속성에서 기본 로컬 코드 페이지 대신 유니 코드 (UTF-8) – 코드 페이지 65001을 선택합니다. 다른 텍스트 파일의 경우이 파일의 올바른 인코딩 (예 : 코드 페이지 1252)을 선택하십시오.
- xml 파일과 같은 텍스트 파일의 경우 클래스
Resources
에는string
포함 된 파일의 이름을 따서 명명 된 유형의 속성이 있습니다. 파일 이름이 예를 들어 RibbonManifest.xml 인 경우 속성의 이름은RibbonManifest
. 코드 파일 Resources.Designer.cs에서 정확한 이름을 찾을 수 있습니다. - 다른 문자열 속성과 마찬가지로 문자열 속성을 사용합니다 (예 :
string xml = Resources.RibbonManifest
. 일반적인 형식은ResourceFileName.IncludedTextFileName
.ResourceManager.GetString
문자열 속성의 get-function이 이미 수행 했으므로 사용하지 마십시오 .
Form Load Event에서 Embedded TXT FILE을 읽습니다.
변수를 동적으로 설정합니다.
string f1 = "AppName.File1.Ext";
string f2 = "AppName.File2.Ext";
string f3 = "AppName.File3.Ext";
Try Catch를 호출하십시오.
try
{
IncludeText(f1,f2,f3);
/// Pass the Resources Dynamically
/// through the call stack.
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
/// Error for if the Stream is Null.
}
IncludeText ()에 대한 Void 만들기, Visual Studio이 작업을 수행합니다. 전구를 클릭하여 CodeBlock을 자동 생성합니다.
생성 된 코드 블록 안에 다음을 넣으십시오.
자원 1
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file1))
using (StreamReader reader = new StreamReader(stream))
{
string result1 = reader.ReadToEnd();
richTextBox1.AppendText(result1 + Environment.NewLine + Environment.NewLine );
}
자원 2
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file2))
using (StreamReader reader = new StreamReader(stream))
{
string result2 = reader.ReadToEnd();
richTextBox1.AppendText(
result2 + Environment.NewLine +
Environment.NewLine );
}
자원 3
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file3))
using (StreamReader reader = new StreamReader(stream))
{
string result3 = reader.ReadToEnd();
richTextBox1.AppendText(result3);
}
반환 된 변수를 다른 곳으로 보내려면 다른 함수를 호출하고 ...
using (StreamReader reader = new StreamReader(stream))
{
string result3 = reader.ReadToEnd();
///richTextBox1.AppendText(result3);
string extVar = result3;
/// another try catch here.
try {
SendVariableToLocation(extVar)
{
//// Put Code Here.
}
}
catch (Exception ex)
{
Messagebox.Show(ex.Message);
}
}
이것이 달성 한 것은 여러 txt 파일을 결합하고 단일 서식있는 텍스트 상자 안에 포함 된 데이터를 읽는 방법입니다. 이 코드 샘플에서 원하는 효과였습니다.
참고 URL : https://stackoverflow.com/questions/3314140/how-to-read-embedded-resource-text-file
'code' 카테고리의 다른 글
JSON을 간단한 사전으로 역 직렬화하는 방법 (0) | 2020.10.02 |
---|---|
모든 jQuery Ajax 요청이 완료 될 때까지 기다리시겠습니까? (0) | 2020.10.02 |
ASP.NET MVC-사용자 지정 IIdentity 또는 IPrincipal 설정 (0) | 2020.10.02 |
addEventListener 대 onclick (0) | 2020.10.02 |
PostgreSQL 오류 : 치명적 : "사용자 이름"역할이 없습니다. (0) | 2020.10.02 |