So I'm writing some code that is going through a directory of .xlsx files and picking the file that was created last. It's a simple task, but there is something a bit strange happening with the Name property of a particular FileInfo object and potentially there are more cases of this occurring.
Here is my code:
DirectoryInfo di = new DirectoryInfo(FolderPath);
FileInfo[] FileArray = di.GetFiles("*.xlsx", SearchOption.AllDirectories);
if (FileArray.Count() != 0)
{
DateTime latestDate = DateTime.MinValue;
string FileName = String.Empty;
foreach (FileInfo File in FileArray)
{
if (File.CreationTime > latestDate)
{
latestDate = File.CreationTime;
FileName = File.FullName;
}
}
}
The FileName is important because I use it to query the latest file for information and display it. However, the Name property of a particular .xlsx file (potentially more) is appearing like this ~$File.xlsx when in fact the file name is really File.xlsx. This causes the FullName property to contain these characters as well.
Is there any way to fix this? What triggers this?
Opening an xlsx file results in Excel creating a hidden file with the same name preceded by "~$". So if one of these Excel files are open at the time you retrieve the content of the directory, you will also get the temp file.
Add a filter that excludes hidden files and your issue is fixed.
Example:
FileAttributes attributes = File.GetAttributes(path);
if((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
{
// Hidden file, just skip it
}
From http://msdn.microsoft.com/en-us/library/system.io.file.getattributes.aspx
~$ indicates that the file is a temporary file used by Microsoft Office. See here for additional information.
Related
System.IO.InvalidDataException: 'Number of entries expected in Central Directory Ending does not match the number of entries in the Central Directory.'
I'm getting this error on a code that i'm making "for fun" when i try to extract an zip file to a folder. Help ;-;
here's my situation: i made a Drag and Drop panel that recieve a file with a unique extension (the file is a zip but i changed the extension to test). Then the program will get the first line of text in the archive, and will create a folder to extract the files with the name given on that first line. But it gets that error on the extract code
string[] Arquivo = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string arquivo in Arquivo)
{
MessageBox.Show(arquivo);
string[] allLines = File.ReadAllLines(arquivo);
string line = string.Empty;
if (allLines.Length >= 1)
{
line = allLines[0];
}
string Diretorio = #"C:\CommunicAlt\" + line;
MessageBox.Show(Diretorio);
if (!Directory.Exists(Diretorio))
{
Directory.CreateDirectory(Diretorio);
}
Path.ChangeExtension(arquivo, ".zip");
ZipFile.ExtractToDirectory(arquivo, Diretorio); //<--Here
I solved it, the problem is: the zip archive has a new line with a text to create a directory, but the visual studio can't extract it if the number of lines on the archive is different drom the default... so it won't extract.
The solution was to leave the zip archive untouched and create a new file with the config info.
I have a C# console application that sends Excel spreadsheet attachments through email.
I have given the file path in App.config. While trying to find the file, the code looks at proper location. But when trying to attach the file inside the foreach statement, it is looking in code's bin folder.
What am I doing wrong here?
DirectoryInfo dir1 = new DirectoryInfo(ConfigurationManager.AppSettings.Get("FilePath"));
FileInfo[] folderFiles = null;
folderFiles = dir1.GetFiles();
foreach (FileInfo aFile in folderFiles)
{
message.Attachments.Add(new Attachment(aFile.Name));
}
You need to use aFile.FullName (includes the full path) rather than aFile.Name (only the filename). If a command is not doing what you expect, you should check the documentation.
Alternatively, you could make it simpler:
string dir1 = ConfigurationManager.AppSettings.Get("FilePath");
foreach(string aFile in Directory.EnumerateFiles(dir1))
{
message.Attachments.Add(new Attachment(aFile));
}
as Directory.EnumerateFiles simply returns the full filenames and you would have to think about not doing so (e.g. by using Path.GetFileName) to do otherwise.
I have an issue with an C# application. I am trying to read some PDF files and load the data into a database.
The application make works good only when the PDF files are in a specific folder. the folder is the debug folder of the project.
I need to load the PDF files from any folder.
public string LecturaPDF(string nombreArchivo)
{
PdfReader lectorPDF = new PdfReader(nombreArchivo);
string TextoPuro = string.Empty;
string[] TextoDividido;
string TextoFinal = string.Empty;
for (int a = 1; a <= lectorPDF.NumberOfPages; a++)
{
ITextExtractionStrategy pdfParser =
new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
TextoPuro = TextoPuro + PdfTextExtractor.GetTextFromPage(lectorPDF, a, pdfParser);
}
lectorPDF.Close();
TextoDividido = TextoPuro.Split('\n');
for (int b = 0; b < TextoDividido.Count(); b++)
{
if (TextoDividido[b].First()== '7')
{
TextoFinal = TextoFinal + TextoDividido[b] + ";";
}
}
return ';' + TextoFinal;
}
the error occur in this line PdfReader lectorPDF = new PdfReader(nombreArchivo);
the error say:
C:\user\me\MyDocuments\Projects\Project1\bin\debug\test.pdf not found
as file or resource
With this function I open a dialog box to select the file and call the function to read the pdf file:
private void cmdProcesar_Click(object sender, RoutedEventArgs e)
{
if (dialogoArchivo.ShowDialog().Value)
{
for (int a = 0; a < dialogoArchivo.FileNames.Count(); a++)
{
lblEstado.Dispatcher.Invoke(DispatcherPriority.Background, (Action)(() => lblEstado.Content =
"Procesando archivos contra Billing..."));
archivo.InsercionArchivo(dialogoArchivo.SafeFileNames[a], G_Fecha,
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.SafeFileNames[a])),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
}
}
This is my first time with C# and I don't know why only works wwhen I read the files from the project debug folder
Any advice will appreciated
Thanks in advance
UPDATE
private void cmdProcesar_Automatico(object sender, RoutedEventArgs e)
{
string carpeta = "C:\\temp";
DirectoryInfo dir = new DirectoryInfo(carpeta);
FileInfo[] documentos = dir.GetFiles("*.pdf");
txtTarifa.Text = "1.48";
foreach (FileInfo archivopdf in documentos)
{
lblEstado.Dispatcher.Invoke(DispatcherPriority.Background, (Action)(() => lblEstado.Content =
"Procesando archivos contra Billing..."));
archivo.InsercionArchivo(archivopdf.Name, G_Fecha,
archivo.LecturaPDF(System.IO.Path.GetFullPath(archivopdf.Name)),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
}
}
I change the function to automatically read all the file in a specific folder and process every file.
But I get the same error:
C:\user\me\MyDocuments\Projects\Project1\bin\debug\test.pdf not found
as file or resource
From the documentation of OpenFileDialog.SafeFileNames (emphasis mine):
Gets an array of file names and extensions for all the selected files in the dialog box. The file names do not include the path.
As it doesn't contain the path, the current path will be used which when you're running in the debugger will be bin\debug by default.
If you know the directory that the file should be chosen from you could add it to the file name (using Path.Combine) but if you would prefer the full path you can use the FileNames property which according to the documentation (again, emphasis mine):
Each file name includes both the file path and the extension. If no files are selected, this method returns an empty array.
In your context you'd need to change this line:
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.SafeFileNames[a])),
to
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.FileNames[a])),
EDIT
To answer the question in your edit - you are getting FileInfo objects for all pdf files in C:\temp but you are then using System.IO.Path.GetFullPath(archivopdf.Name) to get the file path to pass to archivo.LecturaPDF. The documentation for Path.GetFullPath states (emphasis mine again):
This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.
Imagine that you have a FileInfo for the file c:\temp\example.pdf. When you call System.IO.Path.GetFullPath(archivopdf.Name) on that FileInfo you are essentially calling System.IO.Path.GetFullPath("example.pdf"). This will give the file name of example.pdf but it will use the current path for the path which in your case is C:\user\me\MyDocuments\Projects\Project1\bin\debug\ (the path your executable is running from).
This results in a fully qualified file name of C:\user\me\MyDocuments\Projects\Project1\bin\debug\example.pdf which isn't what you want and presumably doesn't exist.
As you already have a FileInfo object the solution is straightforward - you can use the FullName property directly without the need to call GetFullPath. The FullName property will give you the correct fully qualified name of c:\temp\example.pdf.
Your code should therefore read:
archivo.InsercionArchivo(archivopdf.Name, G_Fecha,
archivo.LecturaPDF(archivopdf.FullName),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
i want to create C# mass file renamer, here is my UI
i have created tes folder, inside of tes there's a file which is 1.txt.
i want to create my program to add prefix and suffix to the files, so 1.txt will become
prefix1suffix
but then i got an error
it's said file already exist though there's only one file on tes folder, which is 1.txt how do i make it work ? where's the error comes from ?
i have tried the following code
private void Rename(string prefix, string filepath, string suffix)
{
//i don't use prefix suffix yet to make sure if my function works
DirectoryInfo d = new DirectoryInfo(filepath);
FileInfo[] file = d.GetFiles();
try
{
foreach (FileInfo f in file )
{
File.Move(f.FullName,"stackoverflow");
}
}
catch (Exception e)
{
cmd.cetakGagal(e.ToString(), title);
}
cmd.cetakSukses("Rename Success", title);
}
and it returns same error as the second picture above.
the following picture is tes folder, there's nothing in tes folder except 1.txt
You are calling File.Move() with a full path for your sourceFileName and a relative path for your destFileName. The relative file path is relative to the current working directory and not to the source file path. I expect that a stackoverflow file exists in the current working directory, most likely created the first time you ran this code.
your File.Move is changing them all to StackOverflow not using the prefix and suffix. If you only have one file in the directory it shouldn't be an issue. Are you sure there is only 1 file?
public static void Move(
string sourceFileName,
string destFileName
)
Looking at this answer might be the clue as you are specifying relative path for the destination file. To obtain the current working directory, see GetCurrentDirectory
The sourceFileName and destFileName arguments are permitted to specify
relative or absolute path information. Relative path information is
interpreted as relative to the current working directory.
You should change
File.Move(f.FullName,"stackoverflow");
to
string fileName = f.Name.Replace(f.Extenstion,string.Empty);
string newFileName = string.Format("{0}{1}{2}",prefix,fileName,suffix);
string newFileWithPath = Path.Combine(f.Directory,newFileName);
if (!File.Exists(newFileWithPath))
{
File.Move(f.FullName,newFileWithPath);
}
The code above will give you that error since, after the first run through, "stackoverflow" exists as a file. Make sure that you check if the destination file exists (using File.Exists) before calling File.Move.
Since your goal is renaming, I would suggest using a test folder filled with files rather than using a piecemeal approach. See if something like this helps:
private void Rename(string prefix, string filepath, string suffix)
{
//i don't use prefix suffix yet to make sure if my function works
DirectoryInfo d = new DirectoryInfo(filepath);
FileInfo[] file = d.GetFiles();
try
{
foreach (FileInfo f in file )
{
f.MoveTo(#filepath + #"\" + prefix + f.Name.Insert(f.Name.LastIndexOf('.'),suffix));
}
}
catch (Exception e)
{
cmd.cetakGagal(e.ToString(), title);
}
cmd.cetakSukses("Rename Success", title);
}
on a side note using a listview to display the filenames and the changes before they're committed will help prevent unwanted changes.
I have a file in the storage and I can't check it, because the name of the file is unicode. That's why the FileExist function return with false, but the file is exist, it's sure, because when i list it, the file name will show. The file name is a hungarian word.
IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
// List files
List<String> fileList = new List<String>(fileStorage.GetFileNames("Informations/*"));
(string file in fileList)
{
MessageBox.Show("file: " + file);
// Will appear: "file: Felhasználási Feltételek.html"
}
// Check file: return false
if (fileStorage.FileExists("Informations/Felhasználási Feltételek.html"))
{
}
What is the solution? Thanks
You can game the system I guess, by making your "own" FileExists logic, such as:
private bool FileExists(string name, List<string> fileList)
{
foreach (string file in fileList)
{
if (file == name) return true;
}
return false;
}
and then you can use this to check your file.
I founded the problem:
i copied the file name from windows explorer, i put F2 on the file, ctrl+c and ctrl+v into source code. the file name was correct into code, but when the application was run, the fileName value was wrong and the solution was that i wrote the filename by keyboard.