1st TZipHeader and the stream created in TZipFile.read needs to be destroyed when finished with to remove memory leeks.
in my case TZipFile.read can use a file name or a index number to file to load a stream
The System,zip file contains
procedure Read(const FileName: string; out Stream: TStream; out LocalHeader: TZipHeader; CheckCrc: Boolean = False); overload;
procedure Read(Index: Integer; out Stream: TStream; out LocalHeader: TZipHeader; CheckCrc: Boolean = False); overload;
The CheckCrc if I enter false the IDE underlines the false
If I remove the false the IDE underlines a read in TZipFile.read
with the below code
var
I : integer;
Str: ShortString;
Strm: TMemoryStream;
ZipHeader: TZipHeader;
Begin
FZip := TZipFile.Create;
FZip.Open(FileName, zmReadWrite);
For I := 0 to FZip.FileCount - 1 do
begin
Str := FZip.FileName[I];
If Str = ExtractFile then FZip.Read(I, Strm, ZipHeader, False); ????????
Strm.Free;
ZipHeader.Free;
end;
How should the FZip.Read instruction look like?
Can I ask also why do we have an OUT command does not VAR do the very same thing. Why is their a double up on these commands or what the point of difference?
Maybe its changed in recent versions, which is why your code sample now fails.
Sometimes youāll need to inform ChatGPT of the current class definition and tell it which line is failing in order to get the correct answer. $20/month. Instant answers.
Never used TBites before - sounds very C++ to me
TBites is a name that should be allocated to an object? - but I do not see it used as an object so why not another name?
var Data: TBytes;
...............
stream.WriteBuffer(data[0], length(data));
Is Delphi treating Data as a type of string with bytes instead of Characters as where is the size recorded.
what size is the length 16 bit?
or does it use a zero termination in the bytes
So if I was writing to a TBytes how do I set the parameters up to store data out of a MemoryStream?
I just donāt want to presume this
1/ with the Zip.add statement will it write over the same named file
2/ Updating a file in Zip can I just write straight over the same file with the new data? and with the Zip.add statement.
Ok ā¦ you can Watch a stream variable as " TBytes( stream_variable ) " which maybe shouldnāt be necessary.
[Correction] You get something ā¦ but it doesnāt look correct.
1/ so I have a file name and to add a file I need a file name in the ZipHeader but the name is recorded in TBites and I have a ShortString with my name in it
I can use length(File name) to set the length in the header
2/ to add a file what other values does the file need?
My data is in a TMemoryStream
In the ZipHeader how much space is allocated to put a file name into as a TBytes?
how do you measure that allocated space in TBytes
I can use CopyMemory
Its one thing using length(Bytes) in code to get size
But that is well short of the understanding of TBytes struture and control to sizing of TBytes and how I can use it. what determines the end of TBytes or is it 16 bit-32 bit but records bytes instead of characters.
what is it?
The big question is if a file name all I need to set in the ZipHeader to obtain a file save
or is their some other things that need setting in the ZipHeader
I know Delphi is a lot of work to create that I respect
I just wish ZipHeader was not a C++ record - I wish it was part of the Delphi TZipFile Object, and the Object made the ZipHeader with defaults set at the create time. e.g. being RAD.
2/ Things addressed like accessing a new file that it was accessed correctly
3/ MemoryStream access to internal Zip files as standard
4/ Delphi way to find file names and all names include directories if directories are part of the nameā¦
Its very difficult to know what you are asking most of the time - I suspect its a language barrier but it makes it hard to answer, especially as you rarely provide a clear definition of what you are doing, you jump straight into a problem with code that often demonstrates some gaps in your core pascal understanding.
Letās assume you are saving some form of string content as files into a zip file.
The TZipFile.read command is going to give you a stream. You donāt need to worry about what class that stream is. All you need to know is that is complies with a TStream.
Many classes i.e. a TStringList classes will have a method LoadFromStream
Something like this
var strList := TStringList.create;
strList.loadFromStream(strm);
Otherwise, stream classes like TStringStream or TFileStream can be populated like this
strStrm := TStringStream.create();
strStrm.copyFrom(strm,strm.size);
ShowMessage( strStrm.dataString );
If you wanted to use the TStringReader class, you might take the previous example and then use
StringReader := TStringReader.Create(strStrm.dataString );
Similar functions would apply if you were loading an image into TPicture classes.
If you want to take the stream provided by TZipFile and save it to disk, you might do something like this
var fileToSave := TFileStream.create(FileNameToSave,fmCreate);
fileToSave.copyFrom(strm,strm.size);
Based on the poor description youāve provided I donāt even think you should be using a zip file for your use case.
If you can describe clearly your intended use case for āstoring multiple files in a single fileā then its easier to provide advice.
The way a zip file is formatted, its not intended to be written and then adjusted by having files removed/updated on the fly. You may see this magically happen in zipping tools but in the background the entire zip file is recreated as far as I know.
From older posts you talked about using a single file as kind of like a store for a database. Technology like Contact Information (Plasmatech Software Design) i.e. the iStorage standard or even a database like SQLite/Interbase would be far better choices for the thing I think you are trying to do.
Have you read the ZipHeader yet - System.Zip.TZipHeader - RAD Studio API Documentation
The main distraction is no one is explaining I have a short String that needs to be placed in a TBytes of the ZipHeader and how do I set Sizing of the name. They call it a file name and their is the unexplained complication with file names and directories and the many options in the ZipHeader - never explained.
what Iām trying to do
TZipFile.Add to save a TMemoryStreamās data as file data - No file compression required. Not a TStringlist or something else
2/ ZipHeader needs to be fully set up with file name and everything else required for this file save with I guess TZipFile.Add or what ever else instruction.
3/ I will many times want to update the data of a already existing internal Zip file with a TMemoryStreamās data.
What is complicated to understand about my disruption hear
To do this I need to fully understand how to use TBytes as the file name is recorded in TBytes in the ZipHeader as I have never used TBytes.
So TZipFile is a file manager of many little files and nothing else
Paul_McGeeCommittee
Has explained Delphiās Length to get a size but that is not setting a size
as you can read
I think you are trying to interpret/impose that I should be using something else
Should I be writing my own file manger because no one explains TBytes as the name explains to me its about bytes and may be many bytes.!!! and nothing on the internet is explaining TBytes
Because English came out of German - do I need to learn German without instructions before I can speak English - i think is the requirement that you are turning around and saying I Should not be using TZipfile?
So as I said before
TZipFile object should have
TZipFile.SaveFile(Name: String; FileAttributes: ZipFileAttributes; Compression: ZipCompressionType; {Data for storge} ); and whatever TBytes is - is not RAD because its not documented as it a German Language and not Delphi.
Use Add procedure to add an existing file from the file system - just specify the file name, the other parameters are optional / defaulted.
Use extract to extract a file back to the file system.
You only need to worry about tbytes or tstream parameter functions / procedures if you are doing everything in memory - ie creating the file in your application or displaying it directly from your zip file.
Typically with new tech I have never used I do the simplest thing first and slowly build up the solution checking each step vs trying to complete the entire project in one step.
NB: when you add a file to the zip, the new version of the zipfile with the new file added is already āsavedā and does not need to be saved (via TZipFile.SaveFile) to be updated in the filesystem.
https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Zip.TZipFile.Add
if we take
procedure Add(const FileName: string; const ArchiveFileName: string = āā;
Compression: TZipCompression = zcDeflate); overload;
What overrides what? FileName or ArchiveFileName
Is adding also able to save over an original file
These issues I have no helps or better examples
I only want to record a file name with no path or folders used
you say
Use extract to extract a file back to the file system.
Iām running away from extracting as that the opersite of what Iām doing
talking Delphi hear
So is TBytes how is itās size allocated because I want to put my TMemoryStreamās data in a TBytes may be 5 megs in size
File name is the path to the file you are adding. In the help page you linked it says Data can be added to the archive using the absolute path of a file - thatās the version #1 we are discussing.
Archive file name is the name (and potentially path) of the file as it is stored in the zipfile.
It should overwrite a file if you add another one, but the simplest thing to do is try it and see.