How to open .rtf files as text stream - c#

I am very very novice to c# and .net and trying to understand it.
I am using solution from how to read all files inside particular folder and trying to apply in my below code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace HowToCopyTextFiles
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
foreach (string txtName in Directory.GetFiles(#"C:\Users\Environ ment\Desktop\newfolder","*.rtf"))
{
using (StreamReader sr = new StreamReader(txtName))
{
sb.Append(sr.ReadToEnd());
sb.AppendLine();
}
}
Console.Write(sb.ToString());
Console.ReadLine();
}
}
}
The result is ok but at the end of my test file it shows environment name.
like.
this is content of first file
this is content of second file
↑My environment full name ↑My
environment full name ↑My environment full name (Yes 3 times)
I am using cs-script, Is it due to that?
While using .txt files, it is working fine. so the question is how to properly open .rtf files as text stream?

If rtf file is opened, it sometimes saves super hidden(not visible even show hidden file option) temp file as ~filename.rtf which is also read by c#.
I used code from here: C# - Get a list of files excluding those that are hidden
DirectoryInfo directory = new DirectoryInfo(#"C:\temp");
FileInfo[] files = directory.GetFiles();
var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));
foreach (var f in filtered)
{
Debug.WriteLine(f);
}
This solved my problem.

Related

Can I maintain directory structure when zipping file?

I'm attempting to zip up a handful of files but these files could exist in different directories. The zipping portion is working correctly but I cannot figure out how to get it to preserve the directory structure within the zip file.
Here's what I have so far:
public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
foreach (var item in files)
{
archive.CreateEntryFromFile(item.FullName, item.Name, CompressionLevel.Optimal);
}
}
}
Is this possible?
#ErocM the link provided by #Flydog57 gives you exactly what you want. You are not exploiting the entryName argument correctly (the second argument in your case when calling CreateEntryFromFile).
Independently of which file you are adding to the archive (from same of different folders), you have to structure your archive using the entryName argument the C# api gives to you.
If your file's fullname is /tmp/myfile.txt, and you do archive.CreateEntryFromFile(item.FullName, item.Name), then the archive entry name will be myfile.txt. No folder created as the entry name doesn't contain folder structure in it's name.
However, if you call archive.CreateEntryFromFile(item.FullName, item.FullName), you will then have you file folder structure into the archive.
You can try with your function just changing item.Name into item.FullName.
Just be careful, on windows; if you path is C:\tmp\myfile.txt for instance, the archive will not be extractable correctly. You can then add some little code to remove C: from the full name of your files.
Some examples taking your implementation:
using System;
using System.IO;
using System.Collections.Generic;
using System.IO.Compression;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
FileInfo f1 = new FileInfo(#"/tmp/test1.txt");
FileInfo f2 = new FileInfo(#"/tmp/testdir/test2.txt");
List<FileInfo> files = new();
files.Add(f1);
files.Add(f2);
CreateZipFile(files, #"/tmp/archive.zip");
}
public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
foreach (var item in files)
{
// Here for instance, I put all files in the input list in the same directory, without checking from where they are in the host file system.
archive.CreateEntryFromFile(item.FullName, $"mydir/{item.Name}", CompressionLevel.Optimal);
// Here, I am just using the actual full path of the file. Be careful on windows with the disk name prefix (C:, D:, etc...).
// archive.CreateEntryFromFile(item.FullName, item.FullName, CompressionLevel.Optimal);
}
}
}
}

How to Detect a Compressed File in C#

I'm trying to write a text search routine that scans a directory for a given wildcard file spec and scans the matches for a given search string. Everything works except for when I get to ZIP files. Here's the relevant code:
string fileText = File.ReadAllText(filePath);
foreach (string s in lstSearchStrings.Items)
{
int cnt = CountSubStrings(fileText, s);
lstCounts.Items.Add(cnt.ToString());
}
I know it only uses text-based routines so I probably need to change that. Any help in where to make changes / what to do would be appreciated!
You can use SharpZipLib to read inside zip files.
using ICSharpCode.SharpZipLib.Zip;
using (var zipFile = new ZipFile(#"test.zip"))
{
foreach (ZipEntry entry in zipFile)
{
Console.WriteLine(entry.Name);
}
}
First you detect zip files using extension. Then read those using above method.
string fileText = File.ReadAllText(entry.name);

c# How to populate list of string names into a resource file

I have a list of ~200 strings names that I want to populate into a Resources.resx file.
Is there a simple / easy way to do this, or do I have to copy paste into the editor one at a time. Or modify the underlying code for each option?
Can be done like this. Use your own file format and delimiter.
strings.dat
string001,hello world
string002,this is another
code.cs
using System;
using System.IO;
using System.Text;
using System.Resources;
namespace CreateRF
{
class CreateRF
{
static void Main()
{
string[] lines = File.ReadAllLines(#".\strings.dat", Encoding.UTF8);
using (ResXResourceWriter resx = new ResXResourceWriter(#".\resources.resx"))
{
foreach (string line in lines)
{
string[] pair = line.Split(',');
resx.AddResource(pair[0], pair[1]);
}
}
}
}
}

File is being used by another process except that it's not

I'm currently working on a utility to parse multiple xml files and write the results to a csv file. On the second last line(of code) I get the error:
The process cannot access the file 'W:\SRC\hDefML\myExcelFile.csv' because it is being used by another process.'.
Can someone please help me because I have no idea what's wrong, the file isn't being used by anything else and it's driving me crazy?
Here is my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace GenNameUtility
{
class NameGenerator
{
static void Main(string[] args)
{
var files = from file in Directory.GetFiles("W:\\SRC\\hDefMl\\1.0\\Instrument_Files") orderby file
ascending select file;
StringBuilder sb_report = new StringBuilder();
string delimiter = ",";
sb_report.AppendLine(string.Join(delimiter, "Module", "Generator(s)"));
foreach (var file in files)
{
string filename = Path.GetFileNameWithoutExtension(file);
Console.Write("The HDefML file for {0} contains these EEPROM Generators:", filename);
XDocument hdefml = XDocument.Load(file);
var GeneratorNames = from b in hdefml.Descendants("Generators") select new
{
name = (string)b.Element("GeneratorName")
}.ToString();
StringBuilder sb = new StringBuilder();
foreach (var item in GeneratorNames)
{
Console.Write(" GeneratorName is: {0}", GeneratorNames);
sb_report.AppendLine(string.Join(delimiter, filename, GeneratorNames));
var hdef = File.Create(#"W:\SRC\hDefML\myExcelFile.csv").ToString();
File.WriteAllText(hdef, sb.ToString());
}
}
Console.ReadLine();
}
}
}
You need to close the file after you have written to it. See using.
Also it would be better to open the file before the loop and close it thereafter.
The file is being used by another process... but the process is actually yours.
File.Create returns a FileStream. You're opening the file.. writing to it.. but not closing it. When the new iteration comes around.. the file is still open.
You can try something like this:
using (var file = File.Create(#"W:\SRC\hDefML\myExcelFile.csv")) {
// write content here using file
} // this closes the file automatically.
As suggested though, I would wrap the above outside of the loop, so you're not constantly opening and closing the file.
File.WriteAllText will create a file for you so there's no need to use File.Create beforehand.
File.WriteAllText(#"W:\SRC\hDefML\myExcelFile.csv", sb.ToString());
Your File.Create stream seems to be holding the lock on the file which is why File.WriteAllText is throwing the error.
If you need to use File.Create you can use a StreamWriter to write it out.
using(var fs = File.Create(#"W:\SRC\hDefML\myExcelFile.csv"))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(sb.ToString());
}
as a side note, the above using format is the same as doing
using(var fs = File.Create(#"W:\SRC\hDefML\myExcelFile.csv"))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(sb.ToString());
}
}
so you can use whichever you find more readable.

Strange behavior with FileStreams

I have a list of file names that I will be creating and writing to. I have a foreach loop going through them all something like this
void WriteFiles(byte[] data)
{
foreach (string fileName in fileNames)//fileNames is my List<string>
{
FileStream fs = File.Create(fileName)
fs.Write(data, 0, data.Length);
fs.Close();
}
}
Let's say my list of files is 1.txt, 2.txt, and 3.txt
The strange thing is, 1.txt, 2.txt, and 3.txt are all created. but the data is just written 3 times to 1.txt, and 2.txt and 3.txt are empty. I have double checked in the debugger, and fileName is different each time it loops. I have written many programs that read from and write to files, but I have never encountered any behavior like this. I'm very confused.
EDIT
Perhaps this will make more sense. This is actual code that I have run and produced the problem with, copied and pasted straight from Visual Studio.
using System;
using System.Collections.Generic;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static List<string> fileNames = new List<string>();
static void Main()
{
Directory.CreateDirectory("C:\\textfiles");
fileNames.AddRange(new string[] { "1.txt", "2.txt", "3.txt" });
WriteFiles();
}
static void WriteFiles()
{
foreach (string fileName in fileNames)
{
using (StreamWriter sw = new StreamWriter(File.Create("c:\\textfiles\\" + fileName)))
{
sw.Write("This is my text");
}
}
}
}
}
After executing this, I now have 3 text files (1.txt, 2.txt, 3.txt) in the folder C:\textfiles, none of which existed before.
When I open the files in notepad here's what I've got
1.txt - "This is my textThis is my textThis is my text"
2.txt - nothing
3.txt - nothing
WTF??? This doesn't make sense.
Try using a "using":
using (FileStream fs = File.Create( filename ))
{
fs.Write( data, 0, data.Length );
}
Code looks OK (using would be better instead of .Close).
Most likely your data
empty altogether (data.length == 0)
does not represent text that can be displayed (if you write something like [0,0,0] to a text file it will display nothing.
Your code works perfectly in my test environment so I have no idea what's going on there for you. Are the actual files you're writing to in the same directory? What I'm getting at is whether or not some security issue in your environment could be interfering with writing to files 2 and 3?

Categories

Resources