Julia: Can the HTTP.download function create a directory that doesn't exist? - download

This code failed because the ../data/housing/ directory didn't exist:
function FetchHousingData(url::String, path::String)
println("FetchHousingData " * Dates.format(now(), "HH:MM:SS") )
HTTP.download(url, path)
println("done " * Dates.format(now(), "HH:MM:SS") )
end
housingUrl = "https://raw.githubusercontent.com/ageron/handson-ml2/master/datasets/housing/housing.tgz"
housingPathFile = "../data/housing/housing.tgz"
FetchHousingData(housingUrl, housingPathFile)
Is there a way to have HTTP.download() create a missing directory? I haven't been able to find the docs for HTTP.download.

You can get the docs from the REPL as usual by entering help mode (press ? at the REPL prompt):
help?> HTTP.download
download(url, [local_path], [headers]; update_period=1, kw...)
Similar to Base.download this downloads a file, returning the filename. If the local_path:
• is not provided, then it is saved in a temporary directory
• if part to a directory is provided then it is saved into that directory
• otherwise the local path is uses as the filename to save to.
When saving into a directory, the filename is determined (where possible), from the rules of the HTTP.
• update_period controls how often (in seconds) to report the progress.
• set to Inf to disable reporting
• headers specifies headers to be used for the HTTP GET request
• any additional keyword args (kw...) are passed on to the HTTP request.
There doesn't seem to be a kwarg in HTTP.download to create directories, but you might be interested in isdir:
help?> isdir
isdir(path) -> Bool
Return true if path is a directory, false otherwise.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> isdir(homedir())
true
julia> isdir("not/a/directory")
false
See also isfile and ispath.
and mkdir:
help?> mkdir
mkdir(path::AbstractString; mode::Unsigned = 0o777)
Make a new directory with name path and permissions mode. mode defaults to 0o777, modified by the current file creation mask. This function never creates more than one directory. If the directory already exists, or some intermediate
directories do not exist, this function throws an error. See mkpath for a function which creates all required intermediate directories. Return path.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> mkdir("testingdir")
"testingdir"
julia> cd("testingdir")
julia> pwd()
"/home/JuliaUser/testingdir"

I prefer to use mkpath (also mentioned in the docs showed by Nils) as it creates parent directories and does not produce an error if the directory already exists:
housingPathFile = "../data/housing/housing.tgz"
mkpath(dirname(housingPathFile))

Related

How to test if a folder can be deleted

I am writing a Lua function to delete a folder using Luacom in Windows (version 7 onwards and I can't dictate the version). The folder path is specified in UTF-8 and will contain non-ASCII characters, so os.remove, io.whatever, Penlight and lfs will not work. So far I have (using Luacom to access the Windows com model):
function delFolder(sPath, bForce)
--sPath is a fully specified folder path
--bForce is a Boolean indicating whether the folder should be
--deleted even if it contains read-only files
require('luacom')
fso = luacom.CreateObject("Scripting.FileSystemObject")
--code in here to test that the folder exists,
--and return an error if it does not
fso:DeleteFolder(sPath, bForce)
end
My problem is that, if bForce = false, and the folder is effectively read-only, the operation errors out. I need to be able to test for this situation and return an error instead of attempting the operation.
One possibility is to manipulate the Luacom error handling not to abort on error, and test the last error after the operation:
luacom.config.abort_on_error = false
luacom.config.last_error = nil
fso:DeleteFolder(sPath, bForce)
if luacom.config.last_error then
--return error indicating that the folder cannot be deleted
end
but is there a simpler way, using the com model or some other alternative available in Lua?
Reference for FileSystemObject

Keeping track of current directory per user

I am currently creating a client/server application which is trying to keep track of multiple connected users current directories by way of pairing their unique identifier (username), and a new Dir object to an array of hashes like so:
users = []
user = {:user => "userN", :dir => Dir.new(".")}
users.push(user)
...
Although when accessing the dir key within the users hash, I can't seem to use the objects methods properly.
For example:
users[0][:dir].chdir("../")
Returns undefined methodchrdirfor #<Dir:.>
Likewise the method entries which is supposed to accept 1 argument for listing the contents of a directory, only accepts 0 arguments, and when called with 0 arguments it only lists the current directory initialized when Dir was created.
Is there a simple way to keep track of a user's pseudo location within the filesystem?
Edit:: I found the Pathname class and it sort of implements what I need. I am just wondering now if there is a cleaner way to implementing the cd and ls commands when using it.
#Simulate a single users default directory starting point
$dir = Pathname.pwd
#Create a backup of the current directory, change to new directory,
#test to see if the directory exists and if not return to the backup
def cd(dir)
backup = $dir
$dir += dir
$dir = backup if !($dir.directory?)
end
#Take the array of Pathname objects from entries and convert them
#to their string directory values and return the sorted array
def ls(dir)
$dir.entries.map { |pathobject| pathobject.to_s }.sort
end
Your problem actually isn't using a hash incorrectly, it's that Dir.chdir is a global method that changes the working directory of the current process. Dir.entries is similar.
If you're trying to keep track of a path on a per user basis, you could store it as a File, which can also be a directory. That is, directories are represented as a File, so even though it's called "file", it can still store a directory path.
The answer to my question as I've found out is to use the Pathname class: Pathname
It allows you to use the += operator to transverse the file system, although you will have to manually implement many checks to make sure where you are going to transverse to actually exists.
When I implemented my ls command I simply mapped the output of Pathname.entries, and sorted the results.
def ls(pathname)
pathname.entries.map { |pathobject| pathobject.to_s }.sort
end
This gave you an array of sorted strings of all the files in the current directory that Pathname is set to.
For cd you need to make sure the directory exists and if not revert to the previously good directory.
def cd(pathname, directory_to_move_to)
directory_backup = pathname
pathname += directory_to_move_to
pathname = directory_backup if !(pathname.directory?)
end
Example usage:
my_pathname = Pathname.pwd
cd(my_pathname, "../")
ls(my_pathname)

CreateDirectory creates folder under current directory?

I am using vs 2010 in windows.
In my program, I want to create a new directory under the current directory.
I use
TCHAR szPath[MAX_PATH];
GetModuleFileName( NULL, szPath, MAX_PATH );
And the string of szPath is "E:\A20J\Bin\***.exe".
But when I use:
BOOL bol = CreateDirectory("Path", NULL);
bol becomes 1, which means successful.
But under the "E:\A20J\Bin\", I found no such directory as "Path" even after refreshing, why?
The path of the executable is not indicative of the directory in which the current process is executing. Use GetCurrentDirectory() to detemine the directory in which the process is executing, and the directory "Path" will have been created there. If you wish to create the directory in the same directory as the binary then some string manipulation is required to construct the path.
Note that CreateDirectory() returns non-zero only if it creates the directory. The directory may already exist which you may wish to not treat as a failure (see this old answer of mine Create a directory if it doesn't exist).

Where do the files created with File.new actually get stored in Ruby?

I am creating files from within Ruby scripts and adding stuff to them. But where are these files stored that I am creating?
I'm very new to this, sorry!
The files are created at whatever location you specified. For instance:
f = File.new("another_test.txt","w+")
that will create the file in the current working directory. You specify the path along with the file name. For example:
f = File.new("~/Desktop/another_test.txt","w+") # will create the file on the desktop.
For more details, check the File documentation.
Updated:
Included mu is too short correction.

Where should my windows app store cache and tempfiles? [duplicate]

Currently I am using following function to get the temporary folder path for current user:
string tempPath = System.IO.Path.GetTempPath();
On some machines it gives me temp folder path of current user like:
C:\Documents and Settings\administrator\Local Settings\Temp\
On some machines it gives me system temp folder path like:
C:\Windows\TEMP
MSDN Documentation also says that above API returns current system's temporary folder.
Is there any other API available which gives me current user's temporary folder path like this:
C:\Documents and Settings\administrator\Local Settings\Temp\
System.IO.Path.GetTempPath() is just a wrapper for a native call to GetTempPath(..) in Kernel32.
Have a look at http://msdn.microsoft.com/en-us/library/aa364992(VS.85).aspx
Copied from that page:
The GetTempPath function checks for the existence of environment variables in the following order and uses the first path found:
The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
The path specified by the USERPROFILE environment variable.
The Windows directory.
It's not entirely clear to me whether "The Windows directory" means the temp directory under windows or the windows directory itself. Dumping temp files in the windows directory itself sounds like an undesirable case, but who knows.
So combining that page with your post I would guess that either one of the TMP, TEMP or USERPROFILE variables for your Administrator user points to the windows path, or else they're not set and it's taking a fallback to the windows temp path.
DO NOT use this:
System.Environment.GetEnvironmentVariable("TEMP")
Environment variables can be overridden, so the TEMP variable is not necessarily the directory.
The correct way is to use System.IO.Path.GetTempPath() as in the accepted answer.
I have this same requirement - we want to put logs in a specific root directory that should exist within the environment.
public static readonly string DefaultLogFilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
If I want to combine this with a sub-directory, I should be able to use Path.Combine( ... ).
The GetFolderPath method has an overload for special folder options which allows you to control whether the specified path be created or simply verified.

Resources