I have the code like this:
string[] paths = { Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Test", folder };
string path = System.IO.Path.Combine(paths);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
path += "\\";
string p=path+"test.txt";
try
{
FileStream file = File.Create(p);
TextWriter tw = new StreamWriter(file);
tw.WriteLine("Test: " + 1);
tw.Close();
}
catch(Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
I have the test1:
private void OpenStream(string p)
{
try
{
using (StreamReader s = new StreamReader(p, Encoding.UTF8))
{
MessageBox.Show(s.ReadToEnd(), "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
And the test2:
private void OpenF(string p)
{
try
{
Process.Start(p);
}
catch(Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Everywhere this code works fine, but one user has result:
Test1: OK, message with the text appears,
Test2: Message appears with information that file doesn't exist. I can't find file in this location, and even specific parts of directory "Test", folder, don't appear.
So all in all, stream can read text from the file which doesn't exist. How is this possible? How to prevent this situation?
This problem is only with location Environment.SpecialFolder.LocalApplicationData.
Related
I'm unable to debug the the SaveFileToDisk method. Please me help me out how to resolve the issue. Thanks in advance.
private void Download_TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
try
{
PortalTeacherDairyAttachmentList attachment = ((TappedEventArgs)e).Parameter as PortalTeacherDairyAttachmentList;
byte[] attachmentbyte = attachment.Attachment;
DependencyService.Get<IDownloadManager>().SaveFileToDisk(attachment.FileName,attachmentbyte);
}
catch (Exception ex)
{
}
}
SaveFileToDiskCode:
{
Toast.MakeText(Android.App.Application.Context, "Downloading started...", ToastLength.Long).Show();
var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
var absolutepath = dir.AbsolutePath;
string name = filename;
string filePath = System.IO.Path.Combine(absolutepath, name);
try
{
System.IO.File.WriteAllBytes(filePath, data);
var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
mediaScanIntent.SetData(Uri.FromFile(new File(filePath)));
Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent);
OpenFile(filePath, filename);
Toast.MakeText(Android.App.Application.Context, "File downloaded at" + filePath, ToastLength.Long).Show();
CreateNotificationChannel(name);
}
catch (System.Exception e)
{
System.Console.WriteLine(e.ToString());
Toast.MakeText(Android.App.Application.Context, "Error occured", ToastLength.Long).Show();
}
}
I'm trying to make a program that loads a configuration file from another application.
If the file exists, it loads it and displays a message, but if the configuration file is not valid, it displays an error message and then opens a dialog box to load the correct file. But if the user reloads the wrong file, the same dialog box should appear again but that's when my code fails.
Similarly, if the file did not exist from the beginning, it displays a dialog box to load the file, but if it is given to cancel the dialog box or an incorrect file is selected again, my code fails.
I know that the solution would be to use loops but I'm not sure how to structure it.
Pd: searchfile() is my function to open dialog box and readconfig() is my function to read config file of another application.
strfilenamepath = #"C:\Users\test\dogs.exe.config";
if (File.Exists(strfilenamepath))
{
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
else
{
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
readConfig(strfilenamepath);
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
It is easier to design it if you extract the reading logic to another method that handles exceptions and returns a Boolean to signal the success and the computed result. The TryDoSomething pattern does exactly this.
In pseudo code
public bool TryReadConfig(string path, out string[] valores)
{
valores = null;
try {
valores = read the values;
return true;
} catch {
Display message;
return false;
}
}
The main loop in pseudo code
strfilenamepath = #"C:\Users\test\dogs.exe.config";
while (true) {
if (File.Exists(strfilenamepath) && TryReadConfig(strfilenamepath, out var valores)) {
Do something with the valores;
break;
}
var ofd = new OpenFileDialog{ ... };
if (ofd.ShowDialog() == DialogResult.OK) {
strfilenamepath = ofd.Filename;
} else {
break; // The user canceled the operation.
}
}
You can do something like this:
try
{
//Code to try open the file to memory
}
catch (Exception ex)
{
while (true)
{
MessageBox.Show(#"Select an valid file");
var path = searchFile();
if (string.IsNullOrWhiteSpace(path))
continue;
try
{
//Code to try open the file to memory
}
catch (Exception ex2)
{
MessageBox.Show(#"The selected file is not valid");
continue;
}
break;
}
}
I want to create a Windows Folder the name of the folder will get it from a TextBox.Text that the user will fill in, but inside this folder it should also create automatically an app.config
This is what I got so far:
private void CreateNewCustomer()
{
Directory.CreateDirectory(#"C:\Users\khaab\Documents\visual studio 2015\Projects\ReadingXML\ReadingXML\bin\Debug\Customers\" + CustomerTextBox.Text);
StreamWriter File = new StreamWriter(#"C:\Users\k.abdulrazak\Documents\visual studio 2015\Projects\ReadingXML\ReadingXML\bin\Debug\Customers\app.config");
File.Close();
MessageBox.Show("You have successfully added a customer", "Customer added", MessageBoxButtons.OK);
}
How can I do that?
You should have a variable that holds the root path whether to create the new folder and the app.config file, e.g., string root = Environment.CurrentDirectory. Then the CreateNewCustomer method would look like:
public void CreateNewCustomer()
{
var di = Directory.CreateDirectory(Path.Combine(root, CustomerTextBox.Text));
if (di.Exists)
{
var fs = File.Create(Path.Combine(di.FullName, "app.config"));
fs.Close();
MessageBox.Show("You have successfully added a customer", "Customer added", MessageBoxButtons.OK);
}
}
How about this:
public void SubmitButton_Click(object sender, EventArgs args)
{
var name = CustomerTextBox.Text
if (String.IsNullOrWhiteSpace(name))
{
MessageBox.Show("Enter a customer name!");
return;
}
var result = CreateNewCustomer(name);
if (result)
{
MessageBox.Show("You have successfully added a customer", "Customer added", MessageBoxButtons.OK);
}
else
{
MessageBox.Show("Something went wrong.", "Customer add failed", MessageBoxButtons.OK);
}
}
private bool CreateNewCustomer(string customerName)
{
var result = true;
try
{
var basepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Customers");
var custPath = System.IO.Path.Combine(basepath, customerName);
var appconfigpath = System.IO.Path.Combine(custPath, "app.config");
if (!System.IO.Directory.Exists(custPath))
{
System.IO.Directory.CreateDirectory(custPath);
}
System.IO.File.Create(appconfigpath);
}
catch (Exception ex)
{
System.Diagnostics.Trace.TraceError("Error creating customer folder: {0}", ex);
result = false;
}
return result;
}
I need to save in database file Name and Size in byte from folder and all subfolder.
In this folder lay 1 000 000 files.
And when I use example from msdn it works 4 days, that very slowly.
static void Main(string[] args)
{
string pdxPathDocFiles = System.Configuration.ConfigurationManager.AppSettings["PDX_PathDocFiles"] as string;
if (string.IsNullOrEmpty(pdxPathDocFiles))
{
Console.WriteLine("In the configuration file is missing the path to the root directory - PDX_PathDocFiles.");
}
else
{
if (!Directory.Exists(pdxPathDocFiles))
{
Console.WriteLine("Directory not found");
}
else
{
try
{
Console.WriteLine("rootPath: " + pdxPathDocFiles);
PayDox_EPD19_T20_RGMEntities db = new PayDox_EPD19_T20_RGMEntities();
System.IO.DirectoryInfo rootDir = new DirectoryInfo(pdxPathDocFiles);
db.FileDBRecord.RemoveRange(db.FileDBRecord);
WalkDirectoryTree(rootDir, rootDir.ToString(), db);
db.SaveChanges();
}
catch (Exception)
{
Console.WriteLine("Failed to connect to the database");
}
Console.WriteLine("All ok");
}
}
Console.WriteLine("Bye, Good Day.");
}
static void WalkDirectoryTree(System.IO.DirectoryInfo root, string rootDir, PayDox_EPD19_T20_RGMEntities db)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
try
{
files = root.GetFiles("*.*");
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
db.FileDBRecord.Add(new FileDBRecord { FileName = fi.FullName.Replace(rootDir, ""), FileSize = fi.Length });
}
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
WalkDirectoryTree(dirInfo, rootDir, db);
}
}
db.SaveChanges();
}
When I try another way, it throw-out with exception stack overflow exception.
static void Main(string[] args)
{
string pdxPathDocFiles = System.Configuration.ConfigurationManager.AppSettings["PDX_PathDocFiles"] as string;
if (string.IsNullOrEmpty(pdxPathDocFiles))
{
Console.WriteLine("In the configuration file is missing the path to the root directory - PDX_PathDocFiles.");
}
else
{
if (!Directory.Exists(pdxPathDocFiles))
{
Console.WriteLine("Directory not found");
}
else
{
try
{
Console.WriteLine("rootPath: " + pdxPathDocFiles);
PayDox_EPD19_T20_RGMEntities db = new PayDox_EPD19_T20_RGMEntities();
db.FileDBRecord.RemoveRange(db.FileDBRecord);
db.SaveChanges();
Console.WriteLine("Remove data from table");
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo rootDir2 = new DirectoryInfo(pdxPathDocFiles);
try
{
files = rootDir2.GetFiles("*.*", SearchOption.AllDirectories);
Console.WriteLine("Reed {0} fileName", files.Length);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("You do not have permission to access one or more folders in this directory tree.");
Console.WriteLine(ex.Message);
return;
}
db.FileDBRecord.AddRange(files.Select(x => new FileDBRecord { FileName = x.FullName.Replace(pdxPathDocFiles, ""), FileSize = x.Length }));
db.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("All ok");
}
}
Console.WriteLine("Bye, Good Day.");
}
How make program faster, maybe add multithreading?
For starters, your code isn't async. Break this out into a separate class and make the methods async. This allows the thread to be used while waiting for an IO operation. Anytime your calling the Database or File system use async equivalent methods.
The second thing I would do is try to make is so each transaction is atomic. If you doing something x amount of times, write the program in such a way that each x time can be done is isolation. Once that is done you can run these is parallel by creating a new Task (Task.Run).
Once those 2 are done and the task is still taking a while, look into TPL Dataflow. That can buffer requests for you to optimize your process.
I improved first example from msdn, by adding there TPL library.
Now it working 4 hour, not 4 days.
static void Main(string[] args)
{
string pdxPathDocFiles = System.Configuration.ConfigurationManager.AppSettings["PDX_PathDocFiles"] as string;
if (string.IsNullOrEmpty(pdxPathDocFiles))
{
Console.WriteLine("In the configuration file is missing the path to the root directory - PDX_PathDocFiles.");
}
else
{
if (!Directory.Exists(pdxPathDocFiles))
{
Console.WriteLine("Directory not found");
}
else
{
try
{
Console.WriteLine("rootPath: " + pdxPathDocFiles);
PayDox_EPD19_T20_RGMEntities db = new PayDox_EPD19_T20_RGMEntities();
System.IO.DirectoryInfo rootDir = new DirectoryInfo(pdxPathDocFiles);
db.Database.ExecuteSqlCommand("TRUNCATE TABLE [FileDBRecord]");
db.SaveChanges();
db.Dispose();
Console.WriteLine("Remove data from table");
WalkDirectoryTree(rootDir, rootDir.ToString());
Console.WriteLine("All ok");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Console.WriteLine("Bye, Good Day.");
Console.WriteLine("Processing complete. Press any key to exit.");
Console.ReadKey();
}
static void WalkDirectoryTree(System.IO.DirectoryInfo root, string rootDir)
{
//Console.WriteLine("Go to folder: "+ root.FullName.Replace(rootDir, ""));
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
try
{
files = root.GetFiles("*.*");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
PayDox_EPD19_T20_RGMEntities db = new PayDox_EPD19_T20_RGMEntities();
foreach (var currentElement in files)
{
db.FileDBRecord.Add(new FileDBRecord { FileName = currentElement.FullName.Replace(rootDir, ""), FileSize = currentElement.Length });
}
db.SaveChanges();
db.Dispose();
subDirs = root.GetDirectories();
Parallel.ForEach(subDirs,
currentElement =>
{
try
{
WalkDirectoryTree(currentElement, rootDir);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
});
}
}
}
maybe we can fix your second code.. (untested, but may not throw the exception)
if you test it, let me know if it is faster..
static void Main(string[] args)
{
string pdxPathDocFiles = System.Configuration.ConfigurationManager.AppSettings["PDX_PathDocFiles"] as string;
if (string.IsNullOrEmpty(pdxPathDocFiles))
{
Console.WriteLine("In the configuration file is missing the path to the root directory - PDX_PathDocFiles.");
}
else
{
if (!Directory.Exists(pdxPathDocFiles))
{
Console.WriteLine("Directory not found");
}
else
{
try
{
Console.WriteLine("rootPath: " + pdxPathDocFiles);
PayDox_EPD19_T20_RGMEntities db = new PayDox_EPD19_T20_RGMEntities();
db.FileDBRecord.RemoveRange(db.FileDBRecord);
db.SaveChanges();
Console.WriteLine("Remove data from table");
IList<FileDBRecord> files = null;
System.IO.DirectoryInfo rootDir2 = new DirectoryInfo(pdxPathDocFiles);
try
{
files = rootDir2.GetFiles("*.*", SearchOption.AllDirectories).Select(x => new FileDBRecord { FileName = x.FullName.Replace(pdxPathDocFiles, ""), FileSize = x.Length });
Console.WriteLine("Reed {0} fileName", files.Length);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("You do not have permission to access one or more folders in this directory tree.");
Console.WriteLine(ex.Message);
return;
}
files.Foreach(db.FileDBRecord);
db.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("All ok");
}
}
Console.WriteLine("Bye, Good Day.");
}
I have a form with a File Watcher to which he transfers to multiple addresses all video files placed in a folder. What is the best option so that when multiple files are added to even be able to perform each transfer in a thread. Here's an example of my code:
DockingBarTransferEntities context = new DockingBarTransferEntities();
private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)
{
IEnumerable<Diretorios> directories = context.Diretorios.ToList();
foreach (var destino in directories)
{
try
{
Transfere(e.FullPath,Path.GetFileName(e.FullPath),destino);
}
catch (Exception ex)
{
textBox1.Text += "Error: " + ex.Message;
}
}
}
public void Transfere(string fullPath, string name, Diretorios diretorio)
{
try
{
if (Directory.Exists(diretorio.Caminho))
{
string fileName = Path.GetFileName(fullPath);
fileName = String.Format("{0}\\{1}", diretorio.Caminho, fileName);
FileInfo arquivo = new FileInfo(fullPath);
arquivo.CopyTo(fileName, true);
}
}
catch (Exception ex)
{
}
}
It should be as simple as this:
Task.Factory.StartNew(() => Transfere(e.FullPath, Path.GetFileName(e.FullPath), destino));
instead of calling Transfere directly.