I use FileActivatedEventArgs args to do the file association in my video player app. So I when user double clicks a video file it opens and plays the file in my app, also it gets all the neighbouring files, so I can add them to playlist as well. I use following code for this purpose.
var file=args.Files[0];
StorageFileQueryResult neighboringFilesQuery=args.NeighboringFilesQuery;
var startingIndexunit = await neighboringFilesQuery.FindStartIndexAsync(file);
int startingIndex = Convert.ToInt32(startingIndexunit); //this is where exception occurs
not always but sometimes when I open a file I get a System.OverFlowException because the code tries to enter a very large garbage number into int32 which causes the exception.
After further investigation I have discovered that usually when I double click a file and get neighbor files, I get all the files in NeighborFilesQuery (including the 1 file I clicked to open) so I can just find its index so I can set the start index of my playlist in my app, and play the clicked file at correct position.
But in some other cases for example when I open a .flv or some a .rm file, I get all neighbor files in the neighborfilesQuery but I don't get the file I clicked, so when the code tries to get the index of that file, that file doesn't exist in that list hence I get a garbage index.
So why is this api so inconsistent? Sometimes it includes the clicked file in query files list, and sometimes it doesn't?
Note please note that I am only talking about a single file clicked scenario here and not about multiple files opened together (because in that case the files query is supposed to be empty and that is a different scenario).
According to the documentation, when FindStartIndexAsync, you should expect to see uint.MaxValue.
https://learn.microsoft.com/en-us/uwp/api/windows.storage.search.storagefilequeryresult.findstartindexasync
If we check the NeighboringFilesQuery documentation here: https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.activation.fileactivatedeventargs.neighboringfilesquery, we see that it's not available for all invocations. We'll also notice that none of the mp4 files show in the NeighboringFileQuery, so when we activate by clicking on the mp4, the mp4 is still not in the NeighboringFileQuery list. When you call to get the index, it returns uint.MaxValue since the requested file is not in the query. The exception occurs due to an overflow when trying to convert this to Int32.
For this case, you'll want to check against uint.MaxValue prior to casting/converting to Int32. You should also catch any exception that might occur, since you'll get the overflow for any value greater than int.MaxValue.
Related
So my question is basically, how do i start reading a file from a specific line, like for example line 14 until line 18?
Im working on a simple ContactList app and the only thing missing is deleting the information from a specific name. The user can create a new contact which has a name, a number and an address as information. I want the user to also be able to delete the data of that person by typing in their name. Then, the program should read the name and all of the 4 lines under it and remove them from the text File. How could i achieve this?
You can jump to any offset within a file. However, there isn't any way to know where a particular line begins unless you know the length of every line.
If you are writing a contact app, you should not use a regular text file unless:
You pad line lengths so that you can easily calculate the position of each line.
You are loading the entire file into memory.
You can't. You need to read the first n lines in order to find out which line has which number. Except if your records have a fixed length per line (which is not a good idea - there's always someone with a longer name that you could think of).
Likewise, you can't delete a line from the text file. The space on disk does not move by itself. You need an algorithm that implements safe saving and rearranges the data:
foreach line in input_file:
if line is needed:
write line to temporary_output_file
else:
ignore (don't write = delete)
delete input_file
move temporary_output_file to input_file
Disadvantage: you need about double the disk space while input_file and temporary_output_file both exist.
With safe saving, the NTFS file system driver will give the moved file the same time stamp that it had before deleting the file. Read the Windows Internals 7 book (should be part 2, chapter 11) to understand it in detail.
Depending on how large the contact list is (probably it's less than 10M entries), there's no problem of loading the whole database into memory, deleting the record and then writing everything back.
I have a very simple app that creates a text file (after a button click) and sends it to a certain email address(after another button click). I want to add the ability to change the name of the text file that is created based on how many times the file was sent, or i.e. how many times the app successfully ran till the end. Currently, the name of the text file is fixed.
My idea:
I am thinking of adding a check on start-up of the app to see if another text file exists, lets called it Counter.txt. This will contain the number of times the 'send' button was clicked. If the file doesn't exist, then it will create it and append the number 0. Every time the 'send' button is clicked, it will open Counter.txt and increment that number. Also on a 'send' click, it will email the main textfile that I want to send and adjust the name by appending the number from Counter.txt to it.
I am not sure if this is the best or most efficient method, so would appreciate other suggestions to achieve this. Thanks.
Why not use SharedPreferences to store the number of times the app was launched and increment the value on the onCreate() method of your main Activity?
Then when the mail is sent, the file is renamed based on the SharedPreferences value.
I think it's better than changing the file name each time the app is started.
Here is a good Stack Overflow post on how to use SharedPreferences, you should check it out! There is also another post on how to rename a file here.
Hope this helps!
If you have a relatively small collection of key-values that you'd like to save, you should use the SharedPreferences APIs. ~ Android Developer Documentation
// Create your shared preferences
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
// Write to shared preferences
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("yourkey", yourvalue); // You could store the counter right here
editor.commit();
// Read from shared preferences
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = 0;
int lastcounter = sharedPref.getInt("yourkey", defaultValue);
I have openFileDialog and saveFileDialog with filter (only .dvbcfg extention):
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "DVB Configuration File (*.dvbcfg)|*.dvbcfg";
saveFileDialog.DefaultExt = "dvbcfg";
saveFileDialog.AddExtension = true;
It works properly, but when I'm trying to type filename manually it shows files with any extentions w/o filtering and opens/saves them (first - open file, second - save file):
ScreenShot
How to show only files that matches saveFileDialog.Filter?
P.S. I have overwrite function in saveFileDialog.
UPD I have another option - throw an exception when user selected wrong filetype, but I have no idea how to get only file extention from saveFileDialog.FileName string.
At a certain point, you have to "trust" your users. You can steer them towards good ways of working with your program, but at a certain point, you have to recognise that you've put enough simple barriers in their way to prevent accidental misuse1 but you're unlikely to be able to create enough barriers (in these dialogs) to prevent malicious misuse.
The problem is that using wrong file may cause damage to expensive equipment (DVB-3030 Digital Modulator in this case) even if I'm using try/catch to get variables from files (they need to be integers, in try segment I have Convert.ToInteger32) and variable ranges in if/else checks (for example Frequency range should be 10MHz - 90 MHz with 100Hz step). Since program will be used by students, they can purposely try to break it.
And nothing in your current question (or sought answer) would prevent someone from renaming any arbitrary file to have a .dvbcfg extension.
At this point, you "trust" that the user has given you the filename they wish to use. What you need to do next is to validate the contents of the file. If it has a .dvbcfg extension but isn't actually a valid DVB config file, you need to reject it. If it doesn't have a .dvbcfg extension (hey, maybe they're working with an old file system that only allows 8.3 file names :-)) but turns out to have valid content, why be churlish and reject that file?
I would recommend more than just wrapping ToInteger32 calls in try/catch. Go through the file. Ensure it contains exactly what it should and nothing else. Read each parameter value and probably use TryParse on those. Because your code now "expects" to receive invalid inputs. Then validate ranges, etc.
1Which I'd say you've already got.
I am trying to achieve a file lister, which will list all files in specified path. To do so I used mixture of panel, labels and File objects. The code to achieve this is as follow
label_songlist[i].Text=filename[i];
label_songlist[i].Height=25;
label_songlist[i].Location=new Point(x,y);
label_songlist[i].AutoSize=true;
label_songlist[i].Font=new Font(FontFamily.GenericSansSerif,10);
label_songlist[i].BorderStyle=BorderStyle.FixedSingle;
label_songlist[i].Padding=new Padding(0,0,0,5);
panel.Controls.Add(label_songlist[i]);
This works fine for first 5 file. After first five files it some how add space to left for remaining file giving output something like this
.
However, the value of x is never changed through out the execution of program. I did collect value of x and y for each label and wrote it to file. After execution I checked file. The value of X is 0. No change at all.
Background
I'm developing a simple windows service which monitors certain directories for file creation events and logs these - long story short, to ascertain if a file was copied from directory A to directory B. If a file is not in directory B after X time, an alert will be raised.
The issue with this is I only have the file to go on for information when working out if it has made its way to directory B - I'd assume two files with the same name are the same, but as there are over 60 directory A's and a single directory B - AND the files in any directory A may accidentally be the same as another (by date or sequence) this is not a safe assumption...
Example
Lets say, for example, I store a log that file "E17999_XXX_2111.txt" was created in directory C:\Test. I would store the filename, file path, file creation date, file length and the BOM for this file.
30 seconds later, I detect that the file "E17999_XXX_2111.txt" was created in directory C:\FinalDestination... now I have the task of determining whether;
a) the file is the same one created in C:\Test, therefore I can update the first log as complete and stop worrying about it.
b) the file is not the same and I somehow missed the previous steps - therefore I can ignore this file because it has found its way to the destination dir.
Research
So, in order to determine if the file created in the destination is exactly the same as the one created in the first instance, I've done a bit of research and found the following options:
a) filename compare
b) length compare
c) a creation-date compare
d) byte-for-byte compare
e) hash compare
Problems
a) As I said above, going by Filename alone is too presumptuous.
b) Again, just because the length of the contents of a file is the same, it doesn't necessarily mean the files are actually the same.
c) The problem with this is that a copied file is technically a new file, therefore the creation date changes. I would want to set the first log as complete regardless of the time elapsed between the file appearing in directory A and directory B.
d) Aside from the fact that this method is extremely slow, it appears there's an issue if the second file has somehow changed encoding - for example between ANSII and ASCII, which would cause a byte mis-match for things like ascii quotes
I would like not to assume that just because an ASCII ' has changed to an ANSII ', the file is now different as it is near enough the same.
e) This seems to have the same downfalls as a byte-for-byte compare
EDIT
It appears the actual issue I'm experiencing comes down to the reason for the difference in encoding between directories - I'm not currently able to access the code which deals with this part, so I can't tell why this happens, but I am looking to implement a solution which can compare files regardless of encoding to determine "real" differences (i.e. not those whereby a byte has changed due to encoding)
SOLUTION
I've managed to resolve this now by using the SequenceEqual comparison below after encoding my files to remove any bad data if the initial comparison suggested by #Magnus failed to find a match due to this. Code below:
byte[] bytes1 = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.ASCII, Encoding.GetEncoding(1252).GetBytes(File.ReadAllText(FilePath)));
byte[] bytes2 = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.ASCII, Encoding.GetEncoding(1252).GetBytes(File.ReadAllText(FilePath)));
if (Encoding.ASCII.GetChars(bytes1).SequenceEqual(Encoding.ASCII.GetChars(bytes2)))
{
//matched!
}
Thanks for the help!
You would then have to compare the string content if the files. The StreamReader (which ReadLines uses) should detect the encoding.
var areEquals = System.IO.File.ReadLines("c:\\file1.txt").SequenceEqual(
System.IO.File.ReadLines("c:\\file2.txt"));
Note that ReadLines will not read the complete file into memory.