简体   繁体   中英

Delphi alternatives to some File I/O C++ lib functions?

  • fopen_s <--> OpenFile
  • fclose <--> CloseFile

Is my assumption correct?

I wonder what is better to use, OpenFile or CreateFile. The latter gives more freedom, but is it faster?

Low-level Delphi file handling is done like this:

procedure Proc;
var
  f: file; // or f: TextFile;
begin
  FileMode := fmOpenRead; // or fmOpenWrite or fmOpenReadWrite
  AssignFile(f, 'C:\file.txt');
  try
    // Reset/Rewrite
    // A number of BlockRead/BlockWrite/ReadLn/WriteLn...
  finally
    CloseFile(f);
  end;
end;

This is the classic way of working with files in Delphi, and this is what corresponds to the C++ functions.

OpenFile and CreateFile are not Delphi functions, so they cannot correspond to the C++ functions. Instead, these are functions of the Windows API, which is available in all (Windows) programming languages. The former, OpenFile , is not recommended. Use CreateFile instead. But if you use the Windows API file-handling functions to open/create a file, you should also use these to read/write the file, eg the ReadFile function, and you must finish by using the CloseHandle function.

Notice in particular that OpenFile is a function of the Windows API, whereas CloseFile is a Delphi RTL function, so you cannot even use these together! Delphi: AssignFile -> CloseFile ; Windows API: CreateFile -> CloseHandle .

You should also know, that there are high-level functions for managing files in the Delphi RTL (run-time library). I am sure other users will promote these.

I would use neither in Delphi – I would use streams. Low level file handling is messy and error-prone, it's much better to use higher level routines if you can.

You ask which is faster, OpenFile or CreateFile . They are basically the same, but any method of opening a file is going to map onto the system call anyway so the performance will be the same no matter how you do it. What's more, when does performance for opening a file matter, it's when reading or writing that time is expended.

Any questions about performance are hard to answer without context. The answer for an app which reads thousands of small text files is different from one which streams backups to a tape drive, for example.

Anyway, to stress my original point, take advantage of the excellent high-level framework that Delphi provides, use streams, avoid low-level I/O and enjoy!


So, how does one use a Delphi stream? I'll try to illustrate this with a made up example of writing some text, in a string, to a file.

procedure SaveTextToFile(FileName, Text: string);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  Try
    if Length(Text)>0 then
      Stream.WriteBuffer(Text[1], Length(Text)*SizeOf(Char));
  Finally
    Stream.Free;
  End;
end;

It's pretty self-explanatory. The second parameter to the TFileStream constructor determines the file mode. Here we want to create a brand new file and so if any contents exist, they are removed. You can also specify file sharing with this parameter.

The code to write the buffer out has a little boiler-plate but again is very simple.

Loading it back results in an almost identical routine:

function LoadTextFromFile(FileName: string): string;
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  Try
    SetLength(Result, Stream.Size div SizeOf(Char));
    if Length(Result)>0 then
      Stream.ReadBuffer(Result[1], Length(Result)*SizeOf(Char));
  Finally
    Stream.Free;
  End;
end;

If you wish to seek around the file then you can set the Position property of the stream, or call the Seek() method. The advantage of the latter is that you can seek from current position or end position.

Streams are idiomatic Delphi. They are used pervasively in the RTL and VCL and by 3rd party libraries. They signal errors with exceptions in the native Delphi manner. There are many different stream classes that all derive from a common ancestor and many routines accept this common ancestor.

It's been a long while since I have done any Delphi programming, but I remember that file IO were much better served using TStream suite of classes (TFileStream for file IO). They are essentially the equivalent mechanism of C++'s IO streams library, which is, of course, the preferred way of doing file IO in C++. See this simple example and this wiki .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM