Hello,
I am trying to write some code to create files greater than the 2 Gig limit
of TFileStream. I tried to use some code from deja by Remy at:
groups.google.com/group/borland.public.cppbuilder.language/browse_thread/thread/72a9a073c9e68af6/4ba9c2acf4b1d5b8
When I tried instantiating it in my CPP:
FileName = "c:\newFile.txt";
TSmStream *FS = new TSmStream(FileName);
TSmStream *FS->Size = SomeSize;
I get compiler error: Cannot create instance of Abstract class 'TStream'
Problem is I pass a TFileStream variable(FS) to a number of functions in my
application for processing of it's buffer. So I am hoping to replace the
TFileStream variable with my TSmStream version that handles files greater
than 2 Gigs.
Here is what I did:
H File
//---------------------------------------------------------------------------
#ifndef TSmStreamH
#define TSmStreamH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TSmStream : public TStream
{
private:
HANDLE __hdl;
unsigned __int64 __fastcall getFileSize(void);
void __fastcall setFileSize(unsigned __int64 Ssize);
unsigned __int64 __fastcall GetFilePosition (void);
void __fastcall SetFilePosition(unsigned __int64 delta);
HANDLE __fastcall InitializeHandle (char* path);
protected:
public:
__fastcall TSmStream(char* path);
__fastcall ~TSmStream();
bool __fastcall ReadBuffer(void * dest, const DWORD size);
bool __fastcall WriteBuffer(void * const src, const DWORD size);
bool __fastcall Seek (const unsigned __int64 delta, const DWORD
direction);
bool __fastcall isValid(void);
__published:
__property unsigned __int64 Size = {read=getFileSize,
write=setFileSize};
__property unsigned __int64 Position = {read=GetFilePosition,
write=SetFilePosition};
};
//---------------------------------------------------------------------------
#endif
CPP File
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "TSmStream.h"
//---------------------------------------------------------------------------
__fastcall TSmStream::TSmStream(char* path)
: __hdl(INVALID_HANDLE_VALUE)
{
__hdl = InitializeHandle(path);
}
__fastcall TSmStream::~TSmStream()
{
if ( __hdl != INVALID_HANDLE_VALUE )
CloseHandle(__hdl);
}
unsigned __int64 __fastcall TSmStream::getFileSize(void)
{
ULARGE_INTEGER ul = {0};
ul.LowPart = GetFileSize(__hdl, &ul.HighPart);
if(ul.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
{
// the caller should use GetLastError() to test for error
return 0xFFFFFFFFFFFFFFFF;
}
return (unsigned __int64)ul.QuadPart;
}
void __fastcall TSmStream::setFileSize(unsigned __int64 Ssize)
{
Size = Ssize;
}
unsigned __int64 __fastcall TSmStream::GetFilePosition (void)
{
LARGE_INTEGER ul = {0};
ul.LowPart = SetFilePointer(__hdl, 0, &ul.HighPart, FILE_CURRENT);
if(ul.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
{
// the caller should use GetLastError() to test for error
return 0xFFFFFFFFFFFFFFFF;
}
return (unsigned __int64)ul.QuadPart;
}
void __fastcall TSmStream::SetFilePosition(unsigned __int64 delta)
{
Seek(delta, FILE_BEGIN);
}
HANDLE __fastcall TSmStream::InitializeHandle (char* path)
{
if ( !path ) return INVALID_HANDLE_VALUE;
return CreateFile(path,
GENERIC_READ | GENERIC_WRITE,
0, //do not share FILE_SHARE_READ | FILE_SHARE_WRITE
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
}
bool __fastcall TSmStream::ReadBuffer(void * dest, const DWORD size)
{
DWORD nNumberOfBytesRead = 0;
BOOL result = ReadFile(__hdl, dest, size, &nNumberOfBytesRead,NULL);
return (result && (size == nNumberOfBytesRead));
}
bool __fastcall TSmStream::WriteBuffer(void * const src, const DWORD size)
{
DWORD nNumberOfBytesWritten = 0;
BOOL result = WriteFile(__hdl, src, size, &nNumberOfBytesWritten, NULL);
return (result && (size == nNumberOfBytesWritten));
}
bool __fastcall TSmStream::Seek (const unsigned __int64 delta, const DWORD
direction)
{
// DIRECTION
// FILE_BEGIN The starting point is zero or the beginning of the file.
// FILE_CURRENT The starting point is the current value of the file
pointer.
// FILE_END The starting point is the current end-of-file position.
ULARGE_INTEGER ul = {0};
ul.QuadPart = delta;
// DWORD result = SetFilePointer(__hdl, ul.LowPart, &ul.HighPart,
direction);
DWORD result = SetFilePointer(__hdl, ul.LowPart, (long*)&ul.HighPart,
direction);
if(result == 0xFFFFFFFF && GetLastError() != NOERROR)
return false;
return true;
}
bool __fastcall TSmStream::isValid(void)
{
return ( __hdl != INVALID_HANDLE_VALUE);
}