Amiga.org

Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jettah on January 12, 2004, 02:28:54 PM

Title: Retrieving FileSize in bytes
Post by: Jettah on January 12, 2004, 02:28:54 PM
Hi,

I'm having some troubles in retrieving the number of bytes a file occupies. The documentation on this subject is not entirely clear (to me, at least).

The following piece of code is used:

struct FileInfoBlock *fib;

if (fib = AllocDosObjectTags(DOS_FILEHANDLE, ADO_FH_Mode))
  {if (Examine(, fib))
     {fib_Size>;
     }
   FreeDosObject(DOS_FILEHANDLE, fib);
  }

The program crashes when reaching AllocDosObjectTags() (or AllocDosTags for that matter).
I can find documentation about DOS_FILEHANDLE /* few people need it */, but I cannot find anything on ADO_FH_Mode! I have a peculiar feeling that,as it is a tag list, it requires a certain value, like this:

ADO_FH_Mode, , TAG_END

But what has to be supplied for ???. I can't find anything about it.
Or am I fully lost in paradise of Amiga software developement?

Help! HELP! Mommy, please help me!

Regards,

Tjitte

P.S.: When it (my small contribution of software) gets published someday, your name will be mentioned in the accompanying README!
Title: Re: Retrieving FileSize in bytes
Post by: itix on January 12, 2004, 02:55:16 PM
Quote

if (fib = AllocDosObjectTags(DOS_FILEHANDLE, ADO_FH_Mode))
{if (Examine(, fib))
{fib_Size>;
}
FreeDosObject(DOS_FILEHANDLE, fib);
}


This is completely wrong.

You must alloc FileInfoBlock structure, not filehandle structure! In
addition your taglist is not terminated with TAG_DONE and ADO_FH_MODE
misses tag value.

Allocate DOS_FIB packet and supply an empty taglist (TAG_DONE only)..
Title: Re: Retrieving FileSize in bytes
Post by: Jettah on January 12, 2004, 03:15:42 PM
@itix:

Thanks for your reply.

But, ehm, it, eh, still does not perform the way I intended...

Changed the code to:
struct FileInfoBlock *fib;

if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))
  {if (Examine(, fib)) fib_Size>;
   FreeDosObject(DOS_FIB, fib);
   }

It still crashes...

Regards,

Tjitte
Title: Re: Retrieving FileSize in bytes
Post by: selco on January 12, 2004, 03:40:35 PM
Hello,
Let me give you another solution:

long filesize(FILE *stream)
{
        long curpos, length;
        curpos = ftell(stream);
                  fseek(stream, 0L, SEEK_END);
        length = ftell(stream);
        fseek(stream, curpos, SEEK_SET);
                  return length;
}

This is plain ANSI-C without Amiga-dependencies, so it should work on all machines...
To call it just open your file with fopen() and give the FilePointer to the function. After that you close the file again with fclose().

Hope that helps...


Title: Re: Retrieving FileSize in bytes
Post by: Karlos on January 12, 2004, 05:19:20 PM
Or, if you dont want to use ANSI C IO for it, you can do what selco describes with dos.library Seek(), which will allow you to determiine the length by seeking to the end of the file from the start.
Title: Re: Retrieving FileSize in bytes
Post by: PiR on January 12, 2004, 06:53:31 PM
Hi

I used the stuff, but in bad way, I shouldn't even speak about... But it worked. :-)
Well, as DOS was written in BCPL (at least the virst versions of it), all the used pointers had to be LONG aligned.

On the other hand we know that all the compilers do at least SHORT align. So this is what I did:

struct {
 short dummy;
 struct FileInfoBlock fib;
} buffer;
struct FileInfoBlock *fib = (struct FileInfoBlock *)( ( (long) &buffer.fib )&~3L );

if (Examine(, fib)) fib_Size>;


Now you may kill me.  ;-)
But at least you can try if it crashes.

Good luck
Title: Re: Retrieving FileSize in bytes
Post by: Piru on January 12, 2004, 07:17:18 PM
@selco

This seek method is infinitely slow on FFS and large files, however.

It should be avoided, if only possible.
Title: Re: Retrieving FileSize in bytes
Post by: itix on January 12, 2004, 09:29:53 PM
Quote

if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))


Why you have "(struct FileInfoBlock *)fib" there?
Title: Re: Retrieving FileSize in bytes
Post by: Jettah on January 12, 2004, 10:27:25 PM
Quote

itix wrote:
Quote

if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))


Why you have "(struct FileInfoBlock *)fib" there?


It's there because AllocDosObject() returns a void *.

In the meantime I've isolated the problem into a separate piece of proza:

#include
#include
#include
#include

void main(void)
{struct FileInfoBlock *fib;
  struct Library *DosBase;
  BPTR File, x;
  char *FileName = "RAM:T/Command-0-T5";

  if (DosBase = OpenLibrary("dos.library", 40L))
    {if (File = Lock(FileName, SHARED_LOCK))
      {if ((struct FileInfoBlock *)fib = AllocDosObjectTags(DOS_FIB, TAG_END))
        {if (Examine(File, fib))
          {printf("Name = %s\n", fib->fib_Name);
           printf("Type = %s\n", (fib->fib_DirEntryType > 0) ? "Directory" : "File";
           printf("Size = %ld\n", fib->fib_Size);
          }
        else printf("ERROR\n");
        FreeDosObject(DOS_FIB, fib);
       }
     if (x = Open(FileName, MODE_OLDFILE))
       {printf("File opened\n");
         Close(x);
       }
     UnLock(File);
    }
   else printf("ERROR: No file locked\n");
   CloseLibrary(DosBase);
   }
  else printf("ERROR: No library opened"\n");
}

This gave me the requested results without troubles. So I draw the conclusion that I'm on the very brink of insight into the matter!

Thanks for all your concern to all of you.

Regards,

Tjitte
Title: Re: Retrieving FileSize in bytes
Post by: PiR on January 13, 2004, 01:06:29 PM
Quote
(struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END)


Yep, you have it on the wrong side.
You mean:
fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, TAG_END)
Title: Re: Retrieving FileSize in bytes
Post by: Jettah on January 13, 2004, 08:00:12 PM
Quote

PiR wrote:
Quote
(struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END)


Yep, you have it on the wrong side.
You mean:
fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, TAG_END)


Silly me! You are perfectly correct. Thanks mate! And remember: whenever the piece of proza, in which the construct is used, ever gets published, your name will shine in the accompanying README!

Bye!

Topic closed.
Tjitte
Title: Re: Retrieving FileSize in bytes
Post by: Minuous on February 03, 2004, 08:08:45 PM
IIRC one of the main reasons you're supposed to use AllocDosObject() for this is so that you don't have to worry about alignment issues...