Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How To Open A File?

Posted on 2003-10-27
7
Medium Priority
?
727 Views
Last Modified: 2010-04-05
Hi there,

I am new to Delphi and hasn't been three weeks since I started learning it. I am currently involved in a program in which I have to open a file and read certain bytes out of it one at a time. Like first, 78 bytes and then 100 bytes and so on till the end of file.

But the problem is I don't know much about the syntaxes used to open files. I tried using help and used Assign method. But the problem is when I open the file and use the showmessage it only shows the first two characters and the rest are all blank. Like spaces. But they are not blank. They do contain characters.

Is it the way I am opening the file becuase someone said that I might have to open the file in binary mode or something to fully get al the characters exactly. So can you experts help me out in this situation...

The following is the code that I have been trying to use. And the type of file that I am reading is a file that comes from an equipment. Hope you guys can help me out and kind of explain the amendments made too.

unit StatFileDecoder;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, Buttons, OleServer, CmAdmCtl, NMUUE;

type
   TMain = class(TForm)
    cmd_Process: TBitBtn;
    OD1: TOpenDialog;
    procedure cmd_ProcessClick(Sender: TObject);
    procedure FileProcess(FileName: String);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
   Main: TMain;

implementation

{$R *.dfm}

procedure TMain.cmd_ProcessClick(Sender: TObject);
var
   FileNumber: Integer;
begin
   If OD1.Execute then
   begin
      with OD1.Files do
      for FileNumber:= 0 to Count  -1 do
         FileProcess(Strings[FileNumber]);

   end;
end;

procedure TMain.FileProcess(FileName: String);
var
   File_Content: String;
   File_Handle: TextFile;
begin
   AssignFile(File_Handle,FileName);
   Reset(File_Handle);
   Readln(File_Handle,File_Content);
   showmessage(Copy(File_Content,5,5));
   CloseFile(File_Handle);
end;

end.

0
Comment
Question by:warheat001
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 9631832
The way I'd do it is with FileStreams.  You can open the file in a stream, then seek to the position you need, and read X characters.  For instance:

procedure ReadFile(Filename: String; CharsToCopy: Integer; ReadPosition: Word);
var
  FS: TFileStream;
  Buff: Array of Char;
begin
  FS := TFileStream.Create(Filename, fmOpenRead);
  try
    FS.Seek(ReadPosition, soFromBeginning);
    SetLength(Buff, CharsToCopy);
    FS.Read(Buff, CharsToCopy);
  finally
    FS.Free;
  end;
end;

I haven't tested the above code, but it should work.

If you need any further help, please feel free to ask.

Stu.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9631851
warheat001,
  Your code would work if the file is a text file. If it is a binary file, you would need to do one of the following:
1) Define an appropriate record and read it record-wise.
2) Read byte by byte

For (1), I need to know the exact file structure, and here's the solution for (2):
The code reads the entire file into a dynamic array of bytes, "MyContents".
You can do whatever processing you want with this array once its read.
Hope this helps. Let me know if you need any clarifications.
...Snehanshu

procedure TForm1.Button2Click(Sender: TObject);
Var
  MyFile : File of Byte;
  MyFileName, MyStr : String;
  MyByte: Byte;
  MyContents: Array of byte;
begin
  //give your file name here or pass it as a parameter
  MyFileName := 'c:\abc.txt';
  setlength(MyContents, 0);
  If FileExists(MyFileName) Then
  Begin
    try
    Begin
      AssignFile(MyFile, MyFileName);
      Reset(MyFile);
      MyStr := '';
      While Not EOF(MyFile) Do
      Begin
       Read(MyFile, MyByte);
       //Just to show some output
       MyStr := MyStr + intToStr(MyByte)+',';

       //Dynamically increment length of the array
       setlength(MyContents, Length(MyContents)+1);
       MyContents[High(MyContents)] := MyByte;

      End;
      CloseFile(MyFile);
      ShowMessage(MyStr);
//write code to process MyContents here

//Free array after processing
      setlength(MyContents, 0);
    end
    except on e:Exception do
    begin
      Raise e;
    end;
    end;

  End
  Else
    ShowMessage('File does not exist');

end;
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9631888
Here's a slightly modified code that shows how to process the array :)

...Shu

procedure TForm1.Button2Click(Sender: TObject);
Var
  MyFile : File of Byte;
  MyFileName, MyStr : String;
  MyByte: Byte;
  MyContents: Array of byte;
  MyCtr: Integer;
begin
  //give your file name here or pass it as a parameter
  MyFileName := 'c:\abc.txt';
  setlength(MyContents, 0);
  If FileExists(MyFileName) Then
  Begin
    try
    Begin
      AssignFile(MyFile, MyFileName);
      Reset(MyFile);
      MyStr := '';
      While Not EOF(MyFile) Do
      Begin
        Read(MyFile, MyByte);

        //Dynamically increment length of the array
        setlength(MyContents, Length(MyContents)+1);
        MyContents[High(MyContents)] := MyByte;

      End;
      CloseFile(MyFile);

//write code to process MyContents here
//here's come sample code to show how to access the array
      For MyCtr := low(MyContents) to High(MyContents) Do
        MyStr := MyStr + IntToStr(MyContents[MyCtr])+',';

      ShowMessage(MyStr);
//Free array after processing
      setlength(MyContents, 0);
    end
    except on e:Exception do
    begin
      Raise e;
    end;
    end;

  End
  Else
    ShowMessage('File does not exist');

end;
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:warheat001
ID: 9632068
Thankyou very much  Stuart Johnson for your quick reply.

But could you tell me how I can put that <FS.Read(Buff, CharsToCopy);> into a variable or how I can read it into a variable or put into a database. Just the putting part only.

Thankyou Very Much

0
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 9632677
Hi warheat001,

After testing the code I posted above, it appears it doesn't work with dynamic arrays.  Unfortunately I've just run short of time and I can't code anything at the moment for you, but I will definately do something for you ASAP.

Sorry not to be able to help immediately.

Stuart.
0
 
LVL 3

Expert Comment

by:BJThomsen
ID: 9635754
procedure ReadFromFile;
  var
    FileStream: TFileStream;
    MyString: String;
begin
  FileStream := TFileStream.Create(<filename>,  fmOpenRead or fmShareDenyWrite);
  try
    SetLength(MyString,<length you want to read>);
    FileStream1.Read(MyString[1], <length you want to read>);
  finally
    FileStream.Free;
  end;
  ShowMessage(MyString);
end;
 
0
 
LVL 6

Accepted Solution

by:
swift99 earned 60 total points
ID: 9639012
I would use Blockread, which is what the TFileStream does "under the .hood"
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question