TFileStream.Seek beyond end of file - delphi

we just came across a peculiar behaviour of the TFileStream.Seek (actually that method is inherited from THandleStream) in Delphi 2007:
You can seek beyond the end of file without an error and after the seek you can even read from the file without an error.
The code does basically just call the Windows API function SetFilePointer and seems to do proper error handling. Can somebody explain what's happening here?

The MSDN documentation for SetFilePointer states:
It is not an error to set a file
pointer to a position beyond the end
of the file. The size of the file does
not increase until you call the
SetEndOfFile, WriteFile, or
WriteFileEx function. A write
operation increases the size of the
file to the file pointer position plus
the size of the buffer written, which
results in the intervening bytes
uninitialized.
This is how the file system is designed to work.

Afaik this behaviour (seek beyond end, write block there) is needed to support NTFS sparse files.

Related

What is the result of sample with an uninitialized texture in DirectX?

The OpenGL has its description about this, but how about DirectX?
In my guess, the sample result is float(0, 0, 0, 0), or arise a crash by the driver. Whatever, it just my guess, or partial case if tested it myself only. I want to make it clear.
The uninitialized texture means, did not pass any data with D3DDevice::CreateTexture2D(), and also, did not map nor update resource.
I want to take the description about DirectX 11 version if possible.
From the Create2DTexture function (that you linked):
If you don't pass anything to pInitialData, the initial content of the memory for the resource is undefined. In this case, you need to write the resource content some other way before the resource is read.
Undefined can mean anything, the driver will determine the exact behavior. It's unlikely that it will crash, but as with undefined behavior, anything is possible. A sample from this texture is certainly not guaranteed to be float4(0,0,0,0) as it is with an unbound texture.
It's analogous to accessing uninitialized system memory. The contents might be filled memory written from previous operations that had allocated the same memory (depending on the allocator's behavior). I would suggest if you want consistent behavior, either use an unbound texture instead, or, initialize the contents.
Yes you get 0 for all values its the same if you sample from a null texture.
I cant remember where it was that I read it but I know its in the MSDN doc, I also happen to do this from time to time because I allocate most of the textures\buffers\views at the start and fill as I go and if I sample from null or uninitialized then it just read 0.

Does Ruby on Rails have read stream for files?

Does rails have a way to implement read streams like Node js for file reading?
i.e.
fs.createReadStream(__dirname + '/data.txt');
as apposed to
fs.readFile(__dirname + '/data.txt');
Where I see ruby has
file = File.new("data.txt")
I am unsure of the equivalent in ruby/rails for creating a stream and would like to know if this is possible. The reasons I ask is for memory management as a stream will be delivered piece by piece as apposed to one whole file.
If you want to read a file in Ruby piece-by-piece, there are a host of methods available to you.
IO#each_line/IO::foreach, also implemented in File to iterate over each line of the file. Neither reads the whole file into memory; instead, both simply read up until the next newline, return, and pause reading, barring a possible buffer.
IO#read/IO::read takes a length parameter, which allows you to specify for it to read up to length bytes from the file. This will only read that many, and not the whole thing.
IO::binread does the same as IO::read, but will open the file in binary mode.
IO#readpartial appears to be very similar or identical to IO#read, but is also worth looking at.
IO#getc and IO#gets both read from the file until they reach the end of what they'll return, as far as I can tell.
There are several more that I'm looking for right now.

Should I call Source.Seek(0,soFromBeginning) after TFileStream.Create?

I have seen in quite few places (one example here: http://pascalgamedevelopment.com/archive/index.php/t-1204.html) people doing this.
Embarcadero documentation says nothing about the position of the header in the file/stream after creating the stream.
Conclusion:
Since the documentation does not guaranty the position of the cursor, we should use 'Seek=0'. Even if now the cursor is placed at the beginning of the file, we will never know how this will change in time. Since Embarcadero does not document this, it looks like they reserve the right to change it.
TFileStream.Create just opens file handle and leaves file position where the Win32 put it after the handle was open - at the beginning on the file.
There's no need to Seek to 0 position; you are already there.

How to get Date and Time the picture was taken at?

I am writing a program in Delphi which should get the date and time of the picture which was taken with photo cam and then it would rename the file to include the date+time it found.
So far i have achieved that by opening file as binary and searching for a special order of bytes. These bytes were then followed by the date and then time. So i've come to a problem. Actually few problems.
Because it reads the file 1 byte after another, reading a file is a slow process. If the date was found, it is usually at the start of file, it doesn't take long, however if 'special byte order' was not found, it will read the whole file. So my method is way too slow.
The special byte order may change in some pictures (i have no idea why) even if it was taken with the same camera. So my program sometimes fails to find the date in the file even though it is there.
Windows explorer has no problems finding date in all of the pictures, so i was thinking maybe there are some kind of special functions which could get me what i need?
How do i get the information i need from the picture so it works with all the formats?
Thanks
I think you only need to look at the EXIF information. http://en.wikipedia.org/wiki/Exif
There are some open source tools which accomplish that, but I don't know of anything Delphi specific. If you're not scared of Java, you can have a look at the source code of this open source project: http://sourceforge.net/projects/jexifviewer/ to see how they evaluate the date field.
You can then optimise your reader, to only look at the relevant area. You might want to keep in mind that the Endianness in Java is different to Delphi.
Jules is right about Exif data; you might want to try this Delphi library:
http://delphihaven.wordpress.com/ccr-exif/
This is an amazing site to view Exif data.
http://regex.info/exif.cgi
If it is a graphic file (as in your case), to open it with a dialog box, place a TOpenPictureDialog component on the form.
Also place the component TLabel, for displaying the date of creation of the file.
In the button's place the following code:
if OpenPictureDialog1.Execute then Label1.Caption := DateTimeToStr(FileDateToDateTime(FileAge(OpenPictureDialog1.FileName));
In order to open jpeg and png files in the code, in the line uses you need to add the name of the two libraries, JPEG, PNGImage.
If you have the full address of your file, you can write the code above instead of the code above:
Label1.Caption := DateTimeToStr(FileDateToDateTime(FileAge('full address to file')));
If you only need the date, without the file creation time, then instead of the DateTimeToStr command, use the DateToStr command.

What all APIs are affected by {$IOCHECKS OFF}?

We have some ancient Delphi code (might have even originated as Turbo Pascal code) that uses {$I-}, aka {$IOCHECKS
OFF}, which makes the code use IOResult instead of exceptions for disk I/O errors.
I want to get rid of the {$I-} and bring this code forward into the 1990s, but to do that, I'd like to know what all is affected by {$IOCHECKS OFF}. Does this only affect the crufty old built-in I/O functions like AssignFile / Reset / Rewrite / Append / CloseFile? Or does it affect more modern things like TFileStream as well? More importantly, what else might be affected that I'm not thinking of? (Delphi Basics suggests that it also affects MkDir and RmDir. If it affects those, there have to be more.)
The Delphi 2007 Help topic "Input output checking (Delphi)" (ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html) says that this affects "I/O procedure[s]", and that "I/O procedures are described in the Delphi Language Guide." This doesn't help much, since CodeGear has never shipped a Language Guide, and the last time Borland shipped one was Delphi 5.
Which functions and classes behave differently under {$I-}?
EDIT: The accepted answer gives some great background, but here's the quick summary in alphabetized list form: {$IOCHECKS OFF} only affects the following routines from the System unit.
Append
BlockRead
BlockWrite
ChDir
CloseFile
Eof
Eoln
Erase
FilePos
FileSize
Flush
MkDir
Read
Readln
Rename
Reset
Rewrite
RmDir
Seek
SeekEof
SeekEoln
SetLineBreakStyle
Truncate
Write
Writeln
Since $I is a compiler directive, it can only affect compiler-generated code, and it can only affect code that actually gets compiled.
For those two reasons, it cannot affect things like TFileStream. It's a class in Classes.pas, which is a unit you don't compile. Any code in it is not affected by the $I directive. Furthermore, the compiler doesn't treat that class specially in any way. It's just another ordinary class.
The $I directive affects the language built-in functions that you've mentioned. The compiler generates calls to those functions specially. It also affects calls to write, writeln, and readln. It should also affect BlockRead and BlockWrite.
You can check the source code. Anything that calls SetInOutRes is susceptible to $I. That includes functions that open files (Append, Reset, and Rewrite), as well as anything else that accepts a parameter of type file or TextFile (Flush, BlockRead, BlockWrite, Erase, FilePos, Seek, FileSize, Read, Readln, Write, Writeln, Rename, Eof, SeekEof, Eoln, SeekEol, Truncate, SetLineBreakStyle, and CloseFile). Also, anything that calls InOutError (ChDir, MkDir, amd RmDir).
Notably absent from the list is AssignFile. That function doesn't actually do any I/O. It just sets up the file record so that Append, Reset, and Rewrite will know what to do.
I should point out that looking at the source code is just inference. The $I directive controls whether the compiler will insert calls to the __IOTest function in your own code after you call certain other functions. That function checks the value of InOutRes, and if it's not zero, it raises a run-time error (which may yield an exception if SysUtils is included in your program). We can't check the source code to directly find out what functions are affected by $I (since it's only called in compiler-generated code), so we're really just looking for which functions set InOutRes, with the assumption that they wouldn't bother doing that if they didn't know the compiler would check for it afterward.

Resources