A few years back I posted about a Nike heart rate monitor here. Well that was over three years ago and I guess all good things must come to an end; the chest strap broke beyond repair and Nike no longer manufactures the unit. So I looked for a new heart rate monitor. I found the Garmin FR60. There is a really good review of it here. I really liked the Nike heart rate monitor. The watch was a bit large but it was really simple and didn't lose the signal from the chest piece. The Garmin on the other hand looses the signal more often than I'd like and then goes back to the main screen which is less than ideal. But at the end of the day the Garmin is the best simple heart rate monitor I could find with user changeable batteries. Plus it's really nice to have while mountain unicycling!
Friday, December 3, 2010
Review: Garmin Heart Rate Monitor
Posted by Chris Bensen at 7:00 PM 0 comments
Labels: Review
Thursday, December 2, 2010
New Life in Mono Lake
NASA has found new life in Mono Lake! It isn't like they haven't found new life there before, but this is different. Apparently this bacteria uses arsenic instead of phosphorus for it's DNA.
Mono Lake is one of my favorite places. I took the photo at the top of this post there years ago. It is a stitched from 12 photos in the late fall.
Update: This isn't quite as exciting as the news was leading to believe (big surprise). After reading this article it turns out they put the bacteria in an environment containing high levels of arsenic (which Mono Lake does contain) and reduced the phosphorus and eventually the bacteria substituted arsenic for phosphorus.
Posted by Chris Bensen at 11:03 AM 3 comments
Wednesday, December 1, 2010
New Delphi RTL symlink functions
Symbolic links (symlinks) have been around on *nix for some time but only recently introduced to Windows in Vista with CreateSymbolicLink. Windows 2000 had introduced junction points which is half way there by allowing a link to directory, also known as a soft link (if the file moves the link points nowhere) but does not allow a link to a file.
Windows has a few idiosyncrasies that everyone should be made aware of. Here is a link to Microsoft symlink documentation but there are a few key differences between Windows and *nix. Symlinks in *nix are simply a file with a link target. The target file can be either a directory or a file and could actually change. Windows on the other hand has symlinks to files and symlinks to directories. They are different and cannot be interchanged as they can with *nix.
In the Delphi RTL the goal was to do what made the most sense for the developer. In most cases this is treating the symlink as a file but in other cases as a directory. The only real problem comes with POSIX when checking if a DirectoryExists and trying to find out information on the symlink. The following are notes that I made of the changes to the Delphi RTL functions in SysUtils.pas and IOUtils.pas.
IsRelativePath\TDirectory.IsRelativePath (new)
IsRelativePath returns a boolean value that indicates whether the specified
path is a relative path.
FileCreateSymLink\TFile.CreateSymLink (new, Windows Vista and above)
FileCreateSymLink creates a symbolic link. The parameter Link is the name of
the symbolic link created and Target is the string contained in the symbolic
link. On Windows the target directory must exist at the time of calling FileCreateSymLink.
FileGetSymLinkTarget\TFile.GetSymLinkTarget (new, Windows Vista and above)
FileGetSymLinkTarget reads the contents of a symbolic link. The result is
returned in the symbolic link record given by SymLinkRec.
Note: The access rights of symlinks are unpredictable over network drives. It is
therefore not recommended to create symlinks over a network drive. To enable
remote access of symlinks under Windows Vista and Windows 7 use the command:
"fsutil behavior set SymlinkEvaluation R2R:1 R2L:1"
FileGetSymLinkTarget\TFile.GetSymLinkTarget (new, Windows Vista and above) overload that takes a string
FileGetSymLinkTarget returns the target of a symbolic link.
FileAge
FileAge retrieves the date-and-time stamp of the specified file as a
TDateTime. This version supports all valid NTFS date-and-time stamps
and returns a boolean value that indicates whether the specified
file exists. If the specified file is a symlink the function is performed on
the target file. If FollowLink is false then the date-and-time of the
symlink file is returned.
FileExists
FileExists returns a boolean value that indicates whether the specified
file exists. If the specified file is a symlink the function is performed on
the target file. If FollowLink is false then the symlink file is used
regardless if the link is broken.
files
case 1: file.txt FollowLink = true returns true
case 2: file.txt FollowLink = false returns true
case 3: [does not exist] FollowLink = true returns false
case 4: [does not exist] FollowLink = false returns false
symlink to file
case 5: link.txt -> file.txt FollowLink = true returns true
case 6: link.txt -> file.txt FollowLink = false returns true
case 7: link.txt -> [does not exist] FollowLink = true returns false
case 8: link.txt -> [does not exist] FollowLink = false returns true
directories
case 9: dir FollowLink = true returns false
case 10: dir FollowLink = false returns false
symlink to directories
case 11: link -> dir FollowLink = true returns false
case 12: link -> dir FollowLink = false returns true
case 13: link -> [does not exist] FollowLink = true returns false
case 14: link -> [does not exist] FollowLink = false returns true
DirectoryExists
DirectoryExists returns a boolean value that indicates whether the
specified directory exists (and is actually a directory). If the specified
file is a symlink the function is performed on the target file. If FollowLink
is false then the symlink file is used. If the link is broken DirectoryExists
will always return false.
Notes:
On Windows there are directory symlinks and file symlinks. On POSIX a symlink is created
as a file that just happens to point to a directory.
directories
case 1: dir FollowLink = true returns true
case 2: dir FollowLink = false returns true
case 3: [does not exist] FollowLink = true returns false
case 4: [does not exist] FollowLink = false returns false
symlink to directories
case 5: link -> dir FollowLink = true returns true
case 6: link -> dir FollowLink = false returns true
case 7: link -> [does not exist] FollowLink = true returns false
case 8: link -> [does not exist] FollowLink = false returns true
files
case 9: file.txt FollowLink = true returns false
case 10 file.txt FollowLink = false returns false
case 11: link -> file.txt FollowLink = true returns false
case 12: link -> file.txt FollowLink = false returns false
case 13: file -> [does not exist] FollowLink = true returns false
case 14: file -> [does not exist] FollowLink = false returns true
FileGetAttr
FileGetAttr returns the file attributes of the file given by FileName. The
attributes can be examined by AND-ing with the faXXXX constants defined
above. A return value of -1 indicates that an error occurred. If the
specified file is a symlink then the function is performed on the target file.
If FollowLink is false then the symlink file is used.
FileSetAttr (Windows only)
FileSetAttr sets the file attributes of the file given by FileName to the
value given by Attr. The attribute value is formed by OR-ing the
appropriate faXXXX constants. The return value is zero if the function was
successful. Otherwise the return value is a system error code. If the
specified file is a symlink then the function is performed on the target file.
If FollowLink is false then the symlink file is used.
Note: It is suggested to use TFile.SetAttributes because it is cross platform.
DeleteFile
DeleteFile deletes the file given by FileName. The return value is True if
the file was successfully deleted, or False if an error occurred. DeleteFile
can delete a symlinks and symlinks to directories.
RemoveDir
RemoveDir deletes an existing empty directory. The return value is
True if the directory was successfully deleted, or False if an error
occurred. If the given directory is a symlink to a directory then the
symlink is deleted. On Windows the link can be broken and the symlink
can still be verified to be a symlink.
FileIsReadOnly
FileIsReadOnly tests whether a given file is read-only for the current
process and effective user id. If the file does not exist, the
function returns False. (Check FileExists before calling FileIsReadOnly)
This function is platform portable. If the file specified is a symlink
then the function is performed on the target file.
FileSetReadOnly
FileSetReadOnly sets the read only state of a file. The file must
exist and the current effective user id must be the owner of the file.
On Unix systems, FileSetReadOnly attempts to set or remove
all three (user, group, and other) write permissions on the file.
If you want to grant partial permissions (writeable for owner but not
for others), use platform specific functions such as chmod.
The function returns True if the file was successfully modified,
False if there was an error. This function is platform portable. If the
specified file is a symlink then the function is performed on the target
file.
FileSetDate
FileSetDate sets the OS date-and-time stamp of the file given by FileName
to the value given by Age. The DateTimeToFileDate function can be used to
convert a TDateTime value to an OS date-and-time stamp. The return value
is zero if the function was successful. Otherwise the return value is a
system error code. If the specified file is a symlink then the function is
performed on the target file. If FollowLink is false then the symlink file
is used.
RenameFile
RenameFile renames the file given by OldName to the name given by NewName.
The return value is True if the file was successfully renamed, or False if
an error occurred. If the file specified is a symlink then the function is
performed on the symlink.
FileGetDateTime (new)
Returns all file times associated with a file. If the specified file is a
symlink then the function is performed on the target file. If FollowLink is
false then the symlink file is used.
TSearchRec = record (updated)
Added TimeStamp property
TSymLinkRec = record (new)
TDirectory.Exists
Added FollowLink parameter
TDirectory.GetAttributes
Added FollowLink parameter
TPath.GetAttributes
Added FollowLink parameter
TFile.Exists
Added FollowLink parameter
TFile.GetAttributes
Added FollowLink parameter
FileGetDateTime (new)
Returns the TDateTime of the file's creation time, last access time and last write time.
FileGetDateTimeInfo
FileGetDateTimeInfo returns the date-and-time stamp of the specified file
and supports all valid NTFS date-and-time stamps. A boolena value is returned
indicating whether the specified file exists. If the specified file is a
symlink the function is performed on the target file. If FollowLink is false
then the date-and-time of the symlink file is returned.
TDateTimeInfoRec = record
Used by FileGetDateTimeInfo to return the various date times on demand. It is a public record but only consumable.
Posted by Chris Bensen at 7:00 AM 4 comments
Labels: Delphi