I am writing with Delphi 2009 a little app to edit HTML files. With
HypRef := '../../photos/myjpg.jpg'
If FileExists(ExpandFileName(HypRef)) then ...
I can find out, whether the file exists or not. Is there a function to find out the correct relative path, if FileExists gives a negative answer?
I'm presuming you mean relative to the directory of the main HTML document. You can call SetCurrentDir() to the directory containing the main HTML document, or you can simply prepend that path to the relative one.
if FileExists(ExtractFilePath(MainDocument) + HypRef) then...
You really don't need to call ExpandFileName() since the OS will properly resolve the '..' and '.' pieces. However, if you intend to use the path for identity then they should all be cannonicalized using ExpandFileName().
Related
I use the following to save screen output to a file
writefile("file.txt"),
tex(expression),
closefile()
The above sends the output of the tex() to the file automatically. which is all and well and what I want. (side-point: It also sends an annoying NIL line each time to the file, which I had to parse put later).
Now, when running the above code again, the file is appended to, which is not what I want. I want to either overwrite the file each time, or if there is a way to delete the file, so I can call delete on it before.
I looked at help and not able to find a command to delete a file, and I also see no option to tell writefile() to overwrite the file?
Is there an option or way around this? I am on windows 7, Maxima version: 5.36.1
Lisp: SBCL 1.2.7
I guess you are trying to capture the output of tex into a file. If so, here are a couple of other ways to do it:
tex (expr, destination);
where destination is either a file name (which is appended) or a stream, as created by opena or openw and closed by close. By the way, destination could be false, in which case tex returns a string.
with_stdout (destination, tex (expr));
where again destination is either a file name (which is appended or clobbered, as determined by the global flag file_output_append) or a stream.
with_stdout could be useful if you want to mix in some output not generated by tex, e.g., print("% some commentary");.
Let me explain my situation with some dummy file names.
I am working in directory 'A' which has a sub directory 'a'. I am running a function 'func1' which is present in both folders. 'func1' needs 'file1' & 'file2' during its execution. 'file1' & 'file2' are present in both folders with some parameters changed inside them. It is not possible for me to change file names at all.
Now, the problem is that when I am running 'func1' in 'A', everything is working fine. But, when I run 'func1' in 'a' using 'addpath/rmpath', rather than using 'file1' & 'file2' from 'a', it is using 'file1' & 'file2' from 'A' which is producing wrong results.
Please tell me how can I change path so that when I run 'func1' in sub directory 'a', it always use 'file1' & 'file2' from 'a' rather than directory 'A'.
I hope I am clear in my explanation :S
If I have understood correctly, you are hoping that if you use addpath to add the subdirectory to the search path, Matlab will give the search path precedence over the current directory. Unfortunately, it is precisely the other way around, as per the Matlab documentation: "Functions in the current folder take precedence over functions with the same file name that reside anywhere on the search path." - and this also applies to the load function when reading data files. (incidentally, I suspect that for this reason you are also not running the version of func1 that you think you are running - try typing which func1 to find out).
Anyway, the solution here is to make sure that Matlab picks the right version of file1 and file2, which you could do in several ways:
Change your working directory to a, since the working directory has precedence: cd a
Put the two versions into separate subfolders, e.g. a and b, and use addpath to add them separatley
Change the different versions of func1 to have explicit references to the files, i.e. load('./a/file1')
With addpath and rmpath you modify the search path in Matlab. Your search path basically is a list of folders where Matlab looks for functions. Not for files you want to open.
If you have your files in folder A and this is your current working directory, Matlab will look for the files in A. If you change to a and change your working directory accordingly, Matlab will open the files in a - this has nothing to do with your search path. If you want to open files from a specific directory, use the entire path in the open command:
fileID = fopen('/path/to/A/file1');
In your case, the case may be that the fopen is applied in the way explained above. If you want Matlab to always open files from the current working directory, change it to:
fileID = fopen('file1');
There are some folder with more than 100 files on it.
But all files and folders names broken with wrong encoding names (UTF->ANSI).
"C:\...\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\..."
Regular function Utf8ToAnsi finxing it, but FindFirst can't search folders with names longer than 255 symbols.
It gaves me only 70/100 files.
FindFirst wraps the Win32 API function FindFirstFile, and the Unicode version of that function can search paths up to 32,767 characters long if you prepend \\?\ to the path you're passing in, like \\?\C:\Folder\Folder\*.
Since Delphi 2009 and newer call the Unicode functions for you, you can just use FindFirst and co there. For Delphi 2007 and earlier (ANSI versions), you'll need to call FindFirstFile/FindNextFile/FindClose from Windows.pas directly. For more information check the Naming a file section of the platform SDK.
Do note that using \\?\ disables various bits of path processing though, so make sure it's a fully qualified path without any '.' or '..' entries. You can use the same trick to open file streams, rename, or copy files with longer paths.
The shell (Explorer) doesn't support this though, so you still need to limit those to at most MAX_PATH characters for things like SHFileOperation (to delete to the recycle bin) or ShellExecute. In many cases you can work around the problem by passing in the DOS 8.3 names instead of the long ones. FindFirst's TSearchRec doesn't expose the short names, but FindFirstFile's TWin32FindData structure does as cAlternateFileName.
Change the current directory (ChDir) to the deepest one you know about, and then pass a relative path to FindFirst or FindFirstFile.
No path component in that file name is longer than MAX_PATH characters, so you should be able to work your way into the directories one step at a time.
Beware that multithreaded programs may be sensitive to changes in the current directory since a process has only one current directory shared by all the threads.
I have a file that describes input data, which is split into several other files. In my descriptor file, I first give the path A that tells where all the other files are found.
The originator may set either a relative (to location of the descriptor file) or absolute path.
When my program is called, the user gives the name of the descriptor file. It may not be in the current working directory, so the filename B given may also contain directories.
For my program to always find the input files at the right places, I need to combine this information. If the path A given is absolute, I need to just that one. If it is relative, I need to concatenate it to the path B (i.e. directory portion of the filename).
I thought boost::filesystem::complete may do the job for me. Unfortunately, it seems it is not. I also did not understand how to test wether a path given is absolute or not.
Any ideas?
Actually I was quite misguided first but now found the solution myself. When "base" holds the path A, and filename holds B:
boost::filesystem::path basepath(base), filepath(filename);
if (!basepath.is_complete())
basepath = filepath.remove_leaf() /= basepath;
base = basepath.string();
It works with Linux at least (where it would be very easy to do without boost, but oh well..), still have to test with Windows.
I have this code,
showmessage('C:\TEMP\'+openfiles[openfilelist.ItemIndex].ID);
if removedir('C:\TEMP\'+openfiles[openfilelist.ItemIndex].ID) then
showmessage('Removed')
else
showmessage('Failed');
The message shows C:\TEMP\0 and this directory does exist as the program created it earlier and used files inside it and then later deletes them. I can see the files and directories so I know they're there. The program successfully deletes the files but does not remove the directory.
If I hardcode the directory it works - this means that it accepts the string
C:\TEMP\0 but does not accept C:\TEMP\'+openfiles[openfilelist.ItemIndex].ID both equate to C:\TEMP\0. I cannot hardcode these directories, so what can I do? How do I convert from a string + string to whatever removedir() is expecting. I looked this up at Delphi basics and it's expecting a string.
I'm confused, since string + string = string. What is going on?
Make sure that neither your program nor any other program have the directory as their current working directory. When you recompile the program this may no longer be the case, so it may be a red herring that the hardcoded value works for you.
In addition to the other good answers, you should not be storing your temp folder in C:\TEMP. Use the value returned from GetTempFilename, instead. Unlike C:\TEMP, this location (which varies by operating system) will work on all operating systems, and all levels of user access control. This also eliminates the risk that the location you have hardcoded might also be hardcoded into another system.
If I understood correctly, openfiles[openfilelist.ItemIndex].ID is a string that contains number?
If so, did you check that it does not contain blanks? Something like this:
filename := 'C:\TEMP\' + trim(openfiles[openfilelist.ItemIndex].ID);
showmessage(filename);
if removedir(filename) then
showmessage('Removed')
else
showmessage('Failed');
What type of objects are openfiles and openfilelist?
Do they open folders at all, if so they may still be open when your trying to delete the folder.