Weird behaviour of FileStream in WinForms - winforms

I have a WinForms application that checks for a TXT file in the application directory. There will be only a single line (user's email) or none. the code is like this:
public static string GetUserEmail()
{
string path = Application.StartupPath + "\\mail.txt";
MessageBox.Show(path);
string adres = String.Empty;
if (File.Exists(path))
{
using (StreamReader sr = new StreamReader(path))
{
adres = sr.ReadLine();
}
}
else
{
using (FileStream fs = File.Create(path))
{
using (StreamReader sr = new StreamReader(path))
{
adres = sr.ReadLine();
}
}
}
MessageBox.Show(adres);
return adres;
}
This Seems to work except one really weird behaviour. When I uninstall the program, and re-install, it still finds the file and reads the previous e-mail. I checked the ApplicationDirectory there is no such file, searched Windows, whole C drive, there is noı mail.txt but it still finds and read the mail address that I have entered in the very first installation. Thanks in advance for any help.

First of all, you are making use of Application.Startup. This will return the path where the executable file is present. So, there is no question of looking file to some other location. As you are saying that you searched entire C drive, it's really a strange issue.
I was facing similar issue with Windows Vista and Win 7. In these 2 operating systems, sometimes files get copied to "SysWow" folder as well.

Related

Xamarin.Android: Write something into a file and be able to open it with the computer afterwards

I am trying to write some kind of an external config file for my Xamarin.Android-application. Just .txt and this only needs to contain several strings, so no rocket science^^
e.g. (Sample Goal/Hopefully final content of the text file:)
[TestSection]
test=12345
I tried it with a tutorial and the following code:
//This code snippet is one example of writing a string to a UTF-8 text file and into the internal storage directory of an application:
public void SaveSomethingIntoExternalTextFile(string toWrite)
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "config.txt");
using (var writer = System.IO.File.CreateText(backingFile))
{
writer.WriteLine(toWrite);
}
}
But unfortunately this has no effect. As my only app-specific path is
Phone\Android\data\com.<company_name>.<application_name>\files
I cannot find any file there after running the code above. And even if I create a new file with the computer in the given path, name it as written (config.txt) and run the given code again, still nothing happens (so the string which's passed as parameter into the method unfortunately isn't written into that file as tried).
Just for the sake of completeness, my test application is pretty simple:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SaveSomethingIntoExternalTextFile("[TestSection]");
SaveSomethingIntoExternalTextFile("test="+12345);
}
Can anyone maybe help? What am I doing wrong?
Would be really happy about every answer, thanks in advance and
Best regards
P.S.: If I open the by computer generated text file, even if in the file directory its displayed correctly, the heading of the file says config[1].txt, opening again config[2].txt and so on. Or does that not matter/has nothing to do with my attempt above?
If you use System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), the path is like
/data/data/App3.App3/files/config.txt
It means that you save it in internal storage, you could not see it without root permission,if you want to see it, you can save it in external storage.
public void SaveSomethingIntoExternalTextFile(string toWrite)
{
string path = Android.App.Application.Context.GetExternalFilesDir(null).ToString();
string filepath = Path.Combine(path, "text.txt");
using (var writer = System.IO.File.CreateText(filepath))
{
writer.WriteLine(toWrite);
}
}
The path like :
/storage/emulated/0/Android/data/App3.App3/files/text.txt
Okay via Debugging, I found out that indeed he does write the value, at least I can retrieve it with the following function (I changed the type of the value to integer as in my tutorial (https://learn.microsoft.com/de-de/xamarin/android/platform/files/index#reading-or-writing-to-files-on-internal-storage ) it was integer as well):
//This code snippet provides one way to read an int value that was stored in a text file:
public int ReadSomethingFromTextFile()
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "config.txt");
if (backingFile == null || !System.IO.File.Exists(backingFile))
{
return 0;
}
int count = 0;
using (var reader = new StreamReader(backingFile, true))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (int.TryParse(line, out var newcount))
{
count = newcount;
}
}
}
return count;
}
Nevertheless, I cannot find the written file. Is the Path System.Environment.SpecialFolder.Personal the right one? Or does this point to root directory, where I am always seeking in some kind of user folder?
Because when looking with the debugger what's inside backingFile, it's
/data/data/com.<company_name>.<application_name>/files/config.txt,
and as written in the post above, the only app-specific path I can access via explorer is
Phone/Android/data/com.<company_name>.<application_name>/files.
I read something about having to root my phone in order to be able to access this path? Makes no sense right?
Isn't there some kind of shared folder (/path), whichs accessable not only by application/operating system but also from outside?

Copying a file to the root path in Codename One

In my code I am prompting the user to load a json file.
I am then attempting to copy this file into an sqlite database.
Once I have the data I am then able to manipulate it as needed - but I need to get it there in the first place.
So step 1 is to get the data in.
I have progressed as far as prompting the user to navigate to the file they want - but when I try and read the file I get this error ..
ERROR: resources must reside in the root directory thus must start with a '/' character in Codename One! Invalid resource: file:///tmp/temp3257201851214246357..json
So I think that I need to copy this file to the root directory
I cannot find a link that shows me how to do this.
Here is my code so far ...
case "Import Script":
try
{
JSONParser json = new JSONParser();
if (FileChooser.isAvailable()) {
FileChooser.showOpenDialog(".json", e2-> {
String file = (String)e2.getSource();
if (file == null) {
home.add("No file was selected");
home.revalidate();
} else {
home.add("Please wait - busy importing");
home.revalidate();
String extension = null;
if (file.lastIndexOf(".") > 0) {
extension = file.substring(file.lastIndexOf(".")+1);
}
if ("json".equals(extension)) {
FileSystemStorage fs = FileSystemStorage.getInstance();
try {
InputStream fis = fs.openInputStream(file);
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), file), "UTF-8"))
{
Map<String, Object> data = json.parseJSON(r);
Result result = Result.fromContent(data);
...... I progress from here
The error is occurring on this line ...
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), file), "UTF-8"))
If I hard code a filename and manually place it in the /src folder it works ... like this ...
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), '/test.json'), "UTF-8"))
But that defeats the purpose of them selecting a file
Any help would be appreciated
Thanks
I suggest watching this video.
It explains the different ways data is stored. One of the core sources of confusion is the 3 different ways to store files:
Resources
File System
Storage
getResourceAsStream returns a read only path that's physically embedded in the jar. It's flat so all paths to getResourceAsStream must start with / and must have only one of those. I would suggest avoiding more than one . as well although this should work in theory.
The sqlite database must be stored in file system which is encapsulated as FileSystemStorage and that's really the OS native file system. But you can't store it anywhere you want you need to give the DB name to the system and it notifies you where the file is stored and that's whats explained in the code above.

Writing from persistent data path to streaming asset

I'm trying to get bytes from Application.persistentDataPath to streaming asset and save it as an mp4 file but my code doesnt work.
Here it is :
IEnumerator streamit(){
string filePath ="file:///"+ Path.Combine(Application.persistentDataPath, "Locomotive Part 1.mp4");
Uri uri = new Uri(filePath);
string converted = uri.AbsoluteUri;
WWW www = new WWW(converted);
Debug.Log (www.error);
yield return www;
using (FileStream fs = new FileStream(Application.persistentDataPath+"/example.mp4", FileMode.Append))
foreach(byte data in www.bytes){
fs.WriteByte (data);
}
}
So what am I doing wrong ? Its not working on both IOS and Mac
Oh, I found my problem.
Everything that doesn't work because of empty spaces on the source path. In IOS, you have to change empty spaces with "%20" whenever you are sending a path.
Thanks Anyway !

Application showing an exception"file not found "

I created an application in VS2010 with operating system WINDOWS XP.
Now, I updated the os to WIN 7 and also updated the location of the application.
So, while running the application for opening a file using open dialog box it showing some exception like"File Not Found".
It was working fine with WIN XP, but now it showing this error, if we keep that perticular file in bin folder its working fine , but if we choose a file from other drive or a folder it showing error.
enter code here
string chosen_file = "";
ofd.Title = "Open a file";
ofd.FileName = "";
ofd.Filter = "Text Files(*.txt)|*.txt|Rich Text Box(*.rtb)|*.rtb|Word Document(*.doc)|*.doc|HTML Pages(*.htm)|*.html|Cascading Style Sheet(*.css)|*.css|JAVA(*.java)|*.java|video file(*.wmv)|*.wmv|All Files(*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
chosen_file = ofd.FileName;
// richTextBox2.LoadFile(chosen_file, RichTextBoxStreamType.PlainText);
var fileInfo = new FileInfo(ofd.FileName);
fileInfo.Length.ToString();
byte[] buffer = new byte[fileInfo.Length];
int length = (int)fileInfo.Length;
FileStream fileStream = new FileStream(fileInfo.Name, FileMode.Open, FileAccess.Read);
fileStream.Read(buffer, 0, length);}
My guess is you referenced a hard-coded path, probably to your "Documents" folder, rather than using an environment variable. With the change from XP to 7, that directory changed. I can't recall what the directory was for Windows XP, but it's now /users/username for Windows 7. Either way, you would be better off using an environment variable.
Look through your program for Documents and Settings and see if you can find it. If you go to a command prompt and type set, it should give you a list of environment variables you could use in place of whatever you were using.

Sharepoint 2010 Upload file using Silverlight 4.0

I am trying to do a file upload from Silverlight(Client Object Model) to Sharepoint 2010 library.. Please see the code below..
try{
context = new ClientContext("http://deepu-pc/");
web = context.Web;
context.Load(web);
OpenFileDialog oFileDialog = new OpenFileDialog();
oFileDialog.FilterIndex = 1;
oFileDialog.Multiselect = false;
if (oFileDialog.ShowDialog().Value == true)
{
var localFile = new FileCreationInformation();
localFile.Content = System.IO.File.ReadAllBytes(oFileDialog.File.FullName);
localFile.Url = System.IO.Path.GetFileName(oFileDialog.File.Name);
List docs = web.Lists.GetByTitle("Gallery");
context.Load(docs);
File file = docs.RootFolder.Files.Add(localFile);
context.Load(file);
context.ExecuteQueryAsync(OnSiteLoadSuccess, OnSiteLoadFailure);
}
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
But I am getting the following error
System.Security.SecurityException: File operation not permitted. Access to path '' is denied.
at System.IO.FileSecurityState.EnsureState()
at System.IO.FileSystemInfo.get_FullName()
at ImageUploadSilverlight.MainPage.FileUpload_Click(Object sender, RoutedEventArgs e)
Any help would be appreciated
Thanks
Deepu
Silverlight runs with very restricted access to the client user's filesystem. When using an open-file dialog, you can get the name of the selected file within its parent folder, the length of the file, and a stream from which to read the data in the file, but not much more than that. You can't read the full path of the file selected, and you are getting the exception because you are attempting to do precisely that.
If you want to read the entire content of the file into a byte array, you'll have to replace the line
localFile.Content = System.IO.File.ReadAllBytes(oFileDialog.File.FullName);
with something like
localFile.content = ReadFully(oFileDialog.File.OpenRead());
The ReadFully method reads the entire content of a stream into a byte array. It's not a standard Silverlight method; instead it
is taken from this answer. (I gave this method a quick test on Silverlight, and it appears to work.)

Resources