04-18-2014 10:15 AM - edited 04-18-2014 10:15 AM
You could always have some fun with Regular Expressions
04-18-2014 10:36 AM
@AristosQueue (NI) wrote:
So, we create a database that maps onto a file directory that knows the index used to create each file, and a smart file "session" refnum with semaphore lockout so even if the file isn't created we treat it as already in use ... and then... oh dear...
Or a simple incrementing counter, which should be good enough if all you want is to avoid collisions.
Incidentally, I should point out that I'm not really sold on the whole concept. Usually, I would expect whatever's creating the file to be responsible for generating a relevant file name. If that name is the same as an existing file, it's because it's the same one and it's OK to overwrite it. This doesn't apply when you're downloading files from the web, but as far as I can tell, it does apply in pretty much all the files I create in my programs.
The only situation I can think of where I did need something like this was when I wanted to generate a temporary file, so the name didn't really matter and I used an OpenG function to generate the random name (which, incidentally, caused a bug - the function takes the file name and appends a random 3 digit number. If such a file doesn't exist, it approves it. Otherwise, it tries again. I wasn't bothering to clean up the temp files, so after a couple of months 1000 files were created and I got a call saying "the program gets stuck when I do X". I decided to delete the temp files on exit).
04-18-2014 10:47 AM
I don't know any way to convert a user supplied scan code into a regex expression that I could then embed in a regex expression with a ^ at the end.
Regardless... here's the implementation of this function doing a directory listing, extracting the integer and then using the next available index. Still working in LV 2011.
04-18-2014 10:51 AM - edited 04-18-2014 10:53 AM
Re Race Condition: That is a good argument for including a SubVI which encapsulates two separate subVIs, it is no argument for having a monolithic VI. (And wait, I thought this VI was only going to be called once a fortnight.)
Let's look inside the VI for a moment, specifically at the aforementioned regular expression . There is a SubVI in the palettes called 'Get File Extension' or something similar. It returns the filename and (lowercase) extension. Once again two functions have been combined, getting the extension and converting it to lowercase. Now this new VI comes along which needs the extension, but left alone. Can you reuse the Get File Extension? nope. You see a copy and paste operation has taken place. If a better method to get the extensions comes along, or a bug is found in that regular expression then you have to find every single place you copied it to. And apparently some times it is commented and sometimes not... And as an earlier post mentioned, not all users look at that regular expression and immediately recognize what is going on.
It is simple joint probability. Every function you add to a subVI adds another step and lowers reuse probability.
04-18-2014 11:07 AM
What Yair said.!
Technically its a feasable feeture but we've rolled our own often enough that creating a file name on the fly is usually a sub vi of the souce project and specific to that project. and is often highly customized for that deliverable
"REQ00xyz" Data files wil be generated and sorted into monthly folders with file names appended with user id and moon phase in arc-minutes. Would require me to grab a lunar calander and do some math but the solution gets delivered. I probably would not build a lot of features into that sub.vi and would document it with little more than a reference to the alminac I needed to find.
"Uniquify file-name". is not as easy to solve for the general case without building a rats nest of requirements that take into account edge-case scenarios. Although the write to measuments file express vi seems to have been a good attempt at this. I haven't dug through the whole implementation. I use few express vis and most of my exposure is via forum threads
Leaving "Create or renumber file.vi" in vi.llb (and I'ld love to peek through that folder you tipped) as undocumented or even adding it to "Gems" with an open BD and a brief statement about the method used to generate the number, allows users to decide if their solution could use the limited feature implementation or at least gives them a great example on where to start to "Roll their own" for project "ditty-bop"
Adding it to vi.lib as a documented feature ... now we want the moon! Why, because that's the type of top quality product we expect from NI. And what we get- Thank you!
04-18-2014 12:33 PM
Darin.K wrote:It is simple joint probability. Every function you add to a subVI adds another step and lowers reuse probability.
I agree. But that assumes that I'm willing to take on the support burden for those VIs anyway... I saw your post right as I was finishing up this new attachment. This is what I would preferably be adding to vi.lib -- a lib containing one public VI and a bunch of private subVIs. Why? Because I want the ability to refactor as needed without treating all those subVIs as published APIs that someone else might be using.
The argument against "private" is that if these are well-defined functions then if I need to change them in the future, I should just leave them on disk and issue new versions. That's a maintenance burden and it creates more code bloat. The larger and more complex the *intended* API becomes, the more of the core of it I would ship as private.
04-18-2014 02:03 PM
Any reason you didn't wire through the 'Prompt' input and "Canceled' output?
04-18-2014 02:56 PM
@NJKirchner wrote:
Any reason you didn't wire through the 'Prompt' input and "Canceled' output?
There is no prompt when a path is wired, and with the mode set to create you get an error and no cancellable dialog if the file already exists. Of course the raison d'etre of this VI is to avoid that error.
04-18-2014 03:36 PM
@NJKirchner wrote:
Any reason you didn't wire through the 'Prompt' input and "Canceled' output?
Yes. And I explained it in the comment on the block diagram.
04-18-2014 03:40 PM
The one I din't understand completely is the select in reverse scan from string for interger. I'd probably save some wires and make -1 the default but I'm sure there is a reason.