I want to automate a program that reads a file, processes it and then write it to a new file. The problem is that a new file comes in every day, and the contents are similar, the input file and output file names will change daily. The file name will be in the following format: SAPHR_Joiners_20110323. As you can see the first part of the name will be constant but the date will be unique...... How would i be able to do this?
Thanks alot guys
If you want to read the latest file in a folder, you could query the created date, using System.IO.File.GetCreationTime
In code:
string myFile =
Directory.GetFiles(#"C:\Temp")
.OrderBy<String, DateTime>(file => File.GetCreationTime(file))
.First();
However, if you know that the file-name will follow a strict naming convention, then it is better to access the file by generating the file name as other answers suggest.
Can't you just generate the filename dynamically in your program, and then open the corresponding file? So something like this:
string filename = "SAPHR_Joiners_" + DateTime.Now.ToString("yyyyMMdd");
string[] filecontents = File.ReadAllLines( filename );
Use a FileSystemWatcher class to look for new incoming files if you want prompt respone, otherwise just locate the file based on a current date. If you have further problems, let us know.
Back the days of VB6 one technique that still is in use this days is the folder monitoring
You keep checking if a folder has files, every x in x minutes, or in your case, every day at XX hours for example.
and you could create a Service from your program and that will insure that it will run every time (as long as the machine is on) :)
Those days, in VB6, we didn't had so much as you have today, so, for watching a folder for specific file types (or anything at all) *.* you can use the System.IO.FIleSystemWatcher (example in that page), and to process the file, just use System.IO.TextReader for example
Related
I'm working with files on a case-insensitive (Mac/Windows) file system in C#. But I'd like to find out the real (case-sensitive) name of this file as stored on disk.
I tried making a new FileInfo(filePath) and checking the FullName, but that just gives me back the path I gave it. And the Name property just strips off the directory, again giving me the name as I passed it in, rather than the name of the file actually stored on disk.
I guess I could iterate over all the files in the parent directory, and look for one that best matches the file of interest, but that's going to kill performance. Surely there's an API somewhere that will do this efficiently?
In my test this gives the name as written on disk
var x = Directory.GetFiles(#"E:\temp", "TEST.EXE");
Console.WriteLine(x); // => outputs: E:\temp\test.exe
Is it possible to copy a file or a folder from one location to another without modifying its attribute data? For example if I have a folder on a network drive and it was created on 2/3/2007 and I want to copy it to my c: drive .. but leave the date/time stamp as 2/3/2007...is that possible?
I'm not sure if it is possible; however you can use the methods within System.IO.File and System.IO.Directory to reset these attributes back to what they were originally.
Specifically the SetCreationTime and SetModificationTime methods will be of most value to you in this case.
I did something as shown below:
File.SetCreationTime(tgtFile, File.GetCreationTime(srcFile));
File.SetLastAccessTime(tgtFile, File.GetLastAccessTime(srcFile));
File.SetLastWriteTime(tgtFile, File.GetLastWriteTime(srcFile));
When you copy a file, it will retain the modified date, however the created date will be changed. I doubt there will be an easy way to retain the created date.
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.copy?view=net-7.0
The attributes of the original file are retained in the copied file.
I need to know when a file that I'm downloading was created, or last written to. Just the date is all I need (such as 6/17/2011). Normally, the file's date can be sussed out by its name, such as "DonQuixoteWasRight.2011-06-17.log"
The problem is that the file can have all sorts of different naming formats, perhaps not even containing the date, such as "SanchoPanzaWasLeft.txt"
I thought maybe the FileInfo class would ride in to the rescue, but with this code:
FileInfo fInfo = new FileInfo(SelectedFileName);
//DateTime when = fInfo.CreationTime; //or CreationTimeUtc?
DateTime when = fInfo.LastWriteTime; //or LastWriteTimeUtc?
return when;
...It simply returns the time that I accessed the file (although I neither created it nor explicitly wrote to it). Neither CreationTime nor LastWriteTime return the true CreationTime or LastWriteTime of the file. Is there a way to find out?
It sounds like you're trying to find out when the file was modified on the server.
Unless the server explicitly tells you somehow, there is no way to find that out.
There is no true way to figure this out, whether the file is on a server or even if it is on your local computer, because the last modified date and other metadata can be changed by users.
When I add a picture I want it to create a new random file name because if you add a picture with the same name it will just overwrite.
The is a built-in method Path.GetRandomFileName. It returns a random folder name or file name.
The GetRandomFileName method returns a
cryptographically strong, random
string that can be used as either a
folder name or a file name. Unlike
GetTempFileName, GetRandomFileName
does not create a file. When the
security of your file system is
paramount, this method should be used
instead of GetTempFileName.
If you want to use your extension (e.g. .jpg instead of generated), you could use another helper method Path.ChangeExtension:
string extension = ".jpg";
string fileName = Path.ChangeExtension(
Path.GetRandomFileName(),
extension
);
System.IO.Path.GetRandomFileName gets a file name that is guaranteed to be unique.
As you want to save pictures, you could just use a GUID as the filename:
string filename = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".jpg");
I always do it this way when I need another file extension than .tmp (which files get when you create them via GetTempFileName).
Of course you could create the files via GetTempFileName and then rename them, but then you have to check again if a file with the new name exists...
You could generate a Guid and use that for your file name. Although this would mean that the files are not human readable and have no information as to what the content is.
Name your image using a GUID
For C# you can use: System.Guid.NewGuid().ToString()
You could built it using the current time.
string fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".png";
The above example will format the current time using year, month, day, hours, minutes, seconds, and fractions of a second. (The fraction of a second can be specified with fewer fs if you want it down to one.).
Advantages:
It will sort automatically by the created time in an alphabetically sorted list. (Like default sorting in Windows Explorer.)
It is human readable and provides useful information about the time it is created.
Disadvantages:
If this is a web application (or other sort of multi-thread process) there is a (small) chance of two files getting same name if generated at the same time. This is not an issue if this is a single-thread EXE.
Perhaps you are looking for GetTempFileName.
I would also go with the GUID solution.
Here some code I would use regularly:
public static string GetRandomFileName(string extension)
{
StringBuffer sb = new StringBuffer(Guid.NewGuid().ToString());
if (!string.IsNullOrEmpty(extensions))
{
sb.Append(".");
sb.Append(extension);
}
return sb.ToString();
}
Would provide you with a fine, reusable solution. Put this into your "collection of my greatest moments" - classlibrary and you are good to go.
I'm doing this:
private void LoadSoundFile()
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (openFileDialog1.FileName.EndsWith(".mp3"))
{
txtFileName.Text = openFileDialog1.FileName;
}
else
{
MessageBox.Show("Currently Musicality only supports MP3 files.", "Unsupported file chosen.");
}
}
}
Is there a better way of checking file types or am I doing it the right way?
Having the .mp3 extension doesn't mean it is an mp3, but not having it is an (acceptable) indication that it isn't.
At some point you will call some API to play the file, and it will fail. When it does, you know it's not a playable file. So make sure you handle that with some decent UI too.
Your question seems to ask if the right way to check if a file is MP3 is to look at the end of the filename. As others have said, the answer to that is no. Matt Warren's post can help you if you want to look into the file to see if it is actually mp3 format.
But your comment on Eran Betzalel's answer makes me wonder if you are asking generally whether the right way to check a file extension is to use String.EndsWith().
One thing to notice is that EndsWith(string) is case-sensitive, so the results of:
EndsWith("mp3")
EndsWith("Mp3")
EndsWith("MP3")
and
EndsWith("mP3")
don't all give the same answer. A better test might be:
if (Path.GetExtension(openFileDialog1.FileName).ToLower() == "mp3")
if all you care about is the file extension and not the file contents.
If you actually want to analyse the file (to check if it really is a .mp3) you'll need to look at the specification so you parse it correctly. Here is a good place to start and there is some more info here. This article on the CodeProject goes even further and extracts ID3 tags as well as the header.
This will be better than just checking that the extension is ".mp3", but it's a lot of extra work so it has to be worthwhile.
It really depends on the nature of your program. I think that if you are not developing a security related application, then you can use the simple extension check.
No, because file extension is simply an indicator, it is not a reliable guide to what the file is or contains.
I can name i music file as mySong.zzz and it will still play in Winamp. When you load it you should sample the start of the file to see if it really is an mp3.
You can also set a filter on your open file dialog so that it only allows the user to select mp3 files:
openFileDialog1.Filter = "mp3|*.mp3|All Files|*.*";
I guess the proper way to actually check if it's an MP3 file (this requires that the file be opened) is to look for "magic numbers", sequences of bytes within the binary data that always occur. In this case, you can use the ID3 tag's magic number: ID3v1 tags are stored in the last 128 bytes of the file starting with the bytes "TAG" (hexadecimal "544147"), while ID3v2 tags are stored at the beginning of the file, so the first 3 bytes of the file are "ID3" (hexadecimal "494433"). I don't know if the MP3 frames themselves have simple magic numbers like this. Obviously, this method requires the file to be opened, which could make a scan of a large number of files slower.
If you want to be sure, load the file with this lib http://sourceforge.net/projects/id3dotnet/ it will fail with an exception if not an mp3. Simply create an Id3.Net.Mp3File with filename or stream in constructor an see if it throws an exception