viele Datein in eine packen

Ok danke aebr wenns geht und nur wenn du willst vor 20:50 weil ich (glaub ich) erst mal für ein Tag kein Computer habe Gruß
 
C++:
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <malloc.h>
#include <windows.h>

struct multifile_fentry
{
	char name[256];
	UINT32 len, off;
};

class multifile_save
{
protected:

	struct multifile_fentry *dic;
	UINT32 anz;
	FILE *dat;

	multifile_save(multifile_save &x) {}
	multifile_save &operator=(multifile_save &x) { return *this; }

public:
	multifile_save()
	{
		dat = NULL;
		dic = NULL;
		anz = 0;
	}
	~multifile_save()
	{
		close();
	}

	int open(const char *destfile)
	{
		dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * 0);
		anz = 0;
		if(dic == NULL)
			return 1;
		dat = fopen(destfile, "wb");
		if(dat == NULL)
		{
			free(dic);
			return 2;
		}
		return 0;
	}

	void close()
	{
		fwrite((void *)dic, sizeof(multifile_fentry), anz, dat);
		fwrite((void *)anz, 4, 1, dat);
		fclose(dat);
		free(dic);
		dic = NULL;
		dat = NULL;
		anz = 0;
	}

	int addfromfile(const char *filename, const char *archivename)
	{
		FILE *readfile;
		UINT32 len;
		char buf[1024];
		if(strlen(archivename) > 255)
			return 1;
		readfile = fopen(filename, "rb");
		if(readfile == NULL)
			return 2;
		if((anz % 20) == 0)
		{
			struct multifile_fentry *dic2;
			UINT32 j;
			dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
			if(dic2 == NULL)
			{
				fclose(readfile);
				return 3;
			}
			for(j = 0; j < anz; j++)
			{
				dic2[j].len = dic[j].len;
				dic2[j].off = dic[j].off;
				strcpy(dic2[j].name, dic[j].name);
			}
			free(dic);
			dic = dic2;
		}
		dic[anz].off = ftell(dat);
		len = filelength(fileno(readfile));
		dic[anz].len = len;
		strcpy(dic[anz].name, archivename);
		anz++;
		while(len > 1024)
		{
			fread(buf, 1, 1024, readfile);
			fwrite(buf, 1, 1024, dat);
			len -= 1024;
		}
		fread(buf, 1, len, readfile);
		fwrite(buf, 1, len, dat);
		fclose(readfile);
		return 0;
	}

	int addbytes(const char *bytes, UINT32 bytelen, const char *archivename)
	{
		if(strlen(archivename) > 255)
			return 1;
		if((anz % 20) == 0)
		{
			struct multifile_fentry *dic2;
			UINT32 j;
			dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
			if(dic2 == NULL)
				return 3;
			for(j = 0; j < anz; j++)
			{
				dic2[j].len = dic[j].len;
				dic2[j].off = dic[j].off;
				strcpy(dic2[j].name, dic[j].name);
			}
			free(dic);
			dic = dic2;
		}
		dic[anz].off = ftell(dat);
		dic[anz].len = bytelen;
		strcpy(dic[anz].name, archivename);
		anz++;
		fwrite(bytes, 1, bytelen, dat);
		return 0;
	}
};

class multifile_load
{
protected:

	struct multifile_fentry *dic;
	UINT32 anz;
	FILE *dat;

	multifile_load(multifile_load &x) {}
	multifile_load &operator=(multifile_load &x) { return *this; }

public:
	multifile_load()
	{
		dat = NULL;
		dic = NULL;
		anz = 0;
	}
	~multifile_load()
	{
		close();
	}

	int open(const char *sourcefile)
	{
		dat = fopen(sourcefile, "rb");
		if(dat == NULL)
			return 1;
		fseek(dat, -4, SEEK_END);
		fread((void *)anz, 4, 1, dat);
		dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * anz);
		if(dic == NULL)
		{
			fclose(dat);
			return 2;
		}
		fseek(dat, -4 - (sizeof(multifile_fentry) * anz), SEEK_END);
		fread((void *)dic, sizeof(multifile_fentry), anz, dat);
		return 0;
	}

	void close()
	{
		fclose(dat);
		free(dic);
		dic = NULL;
		dat = NULL;
		anz = 0;
	}

	UINT32 getlength(const char *archivename)
	{
		UINT32 i;
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return -1;
		return dic[i].len;
	}

	int readtofile(const char *filename, const char *archivename)
	{
		FILE *writefile;
		UINT32 len, i;
		char buf[1024];
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return 1;
		writefile = fopen(filename, "wb");
		if(writefile == NULL)
			return 2;
		fseek(dat, dic[i].off, SEEK_SET);
		len = dic[i].len;
		while(len > 1024)
		{
			fread(buf, 1, 1024, dat);
			fwrite(buf, 1, 1024, writefile);
			len -= 1024;
		}
		fread(buf, 1, len, dat);
		fwrite(buf, 1, len, writefile);
		fclose(writefile);
		return 0;
	}

	int readbytes(char *bytes, UINT32 maxbytelen, const char *archivename)
	{
		UINT32 i;
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return 1;
		if(dic[i].len < maxbytelen)
			maxbytelen = dic[i].len;
		fread(bytes, 1, maxbytelen, dat);
		return 0;
	}
};

int main()
{
	return 0;
}

Gruß
 
Danke!
Aber ne kurze erklärung? Ist da noch was zu machen? Also 2 Bilder rein und dann das zweite anzeigen/öffne was auch immer?
Dann hast dus geschafft :D
MFG
 
Also

Beispiel zum Abspeichern der zwei Bilder a.jpg und b.bmp in einer Datei beide.xyz
C++:
multifile_save speicherer;
speicherer.open("beide.xyz");
speicherer.addfromfile("a.jpg", "a.jpg");
speicherer.addfromfile("b.bmp", "b.bmp");
speicherer.close();
Der zweite Parameter beim addfromfile kann irgendein beliebiger Name sein, muss nicht der Dateiname sein.
Damit du das Bild wieder rausbekomsmt brauchst du dann diesen Namen vom zweiten Parameter.

Rückgabewerte soltlen noch geprüft werden: 0 ist immer OK, was anderes ist ein Fehler.
Nur close hat keinen Returnwert.

Was man beim Abspeichern sonst noch machen kann: Als Quelle statt einer Datei ein Bytearray nehmen, mit addbytes.

Herauslesen von a.jpg in eine Datei
C++:
multifile_load leser;
leser.open("Beide.xyz");
leser.readtofile("a.jpg", "a.jpg");
leser.close();
Der zweite Parameter beim readtofile ist wieder der frei wählbare Name.
Erster Parameter ist der neue echte Dateiname.

Rückgabewerte sollten auch hier geprüft werden.
Außerdem kann man wieder optional die Daten in ein Bytearray holen, mit readbytes.
Wieviel Byte eines der gespeicherten Bilder hat, erfährt man mit getlength.

Achtung: Es lässt sich zwar kompilieren, ich habs aber nicht wirklich gründlich getestet.
Falls was nicht funktioniert melde dich nocheinmal

Gruß
 
Zuletzt bearbeitet:
So habs jetzt getestet dann kam Test.exe Funktioniert nicht mehr.
Dann habe ich es im debug ausgeführt und in void close bei multifile_save kommt zugriffsverletzung in der zeile:
C++:
fwrite((void *)anz, 4, 1, dat);
vollständiger code:
C++:
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <malloc.h>
#include <windows.h>
 
struct multifile_fentry
{
    char name[256];
    UINT32 len, off;
};
 
class multifile_save
{
protected:
 
    struct multifile_fentry *dic;
    UINT32 anz;
    FILE *dat;
 
    multifile_save(multifile_save &x) {}
    multifile_save &operator=(multifile_save &x) { return *this; }
 
public:
    multifile_save()
    {
        dat = NULL;
        dic = NULL;
        anz = 0;
    }
    ~multifile_save()
    {
        close();
    }
 
    int open(const char *destfile)
    {
        dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * 0);
        anz = 0;
        if(dic == NULL)
            return 1;
        dat = fopen(destfile, "wb");
        if(dat == NULL)
        {
            free(dic);
            return 2;
        }
        return 0;
    }
 
    void close()
    {
        fwrite((void *)dic, sizeof(multifile_fentry), anz, dat);
        fwrite((void *)anz, 4, 1, dat);
        fclose(dat);
        free(dic);
        dic = NULL;
        dat = NULL;
        anz = 0;
    }
 
    int addfromfile(const char *filename, const char *archivename)
    {
        FILE *readfile;
        UINT32 len;
        char buf[1024];
        if(strlen(archivename) > 255)
            return 1;
        readfile = fopen(filename, "rb");
        if(readfile == NULL)
            return 2;
        if((anz % 20) == 0)
        {
            struct multifile_fentry *dic2;
            UINT32 j;
            dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
            if(dic2 == NULL)
            {
                fclose(readfile);
                return 3;
            }
            for(j = 0; j < anz; j++)
            {
                dic2[j].len = dic[j].len;
                dic2[j].off = dic[j].off;
                strcpy(dic2[j].name, dic[j].name);
            }
            free(dic);
            dic = dic2;
        }
        dic[anz].off = ftell(dat);
        len = filelength(fileno(readfile));
        dic[anz].len = len;
        strcpy(dic[anz].name, archivename);
        anz++;
        while(len > 1024)
        {
            fread(buf, 1, 1024, readfile);
            fwrite(buf, 1, 1024, dat);
            len -= 1024;
        }
        fread(buf, 1, len, readfile);
        fwrite(buf, 1, len, dat);
        fclose(readfile);
        return 0;
    }
 
    int addbytes(const char *bytes, UINT32 bytelen, const char *archivename)
    {
        if(strlen(archivename) > 255)
            return 1;
        if((anz % 20) == 0)
        {
            struct multifile_fentry *dic2;
            UINT32 j;
            dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
            if(dic2 == NULL)
                return 3;
            for(j = 0; j < anz; j++)
            {
                dic2[j].len = dic[j].len;
                dic2[j].off = dic[j].off;
                strcpy(dic2[j].name, dic[j].name);
            }
            free(dic);
            dic = dic2;
        }
        dic[anz].off = ftell(dat);
        dic[anz].len = bytelen;
        strcpy(dic[anz].name, archivename);
        anz++;
        fwrite(bytes, 1, bytelen, dat);
        return 0;
    }
};
 
class multifile_load
{
protected:
 
    struct multifile_fentry *dic;
    UINT32 anz;
    FILE *dat;
 
    multifile_load(multifile_load &x) {}
    multifile_load &operator=(multifile_load &x) { return *this; }
 
public:
    multifile_load()
    {
        dat = NULL;
        dic = NULL;
        anz = 0;
    }
    ~multifile_load()
    {
        close();
    }
 
    int open(const char *sourcefile)
    {
        dat = fopen(sourcefile, "rb");
        if(dat == NULL)
            return 1;
        fseek(dat, -4, SEEK_END);
        fread((void *)anz, 4, 1, dat);
        dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * anz);
        if(dic == NULL)
        {
            fclose(dat);
            return 2;
        }
        fseek(dat, -4 - (sizeof(multifile_fentry) * anz), SEEK_END);
        fread((void *)dic, sizeof(multifile_fentry), anz, dat);
        return 0;
    }
 
    void close()
    {
        fclose(dat);
        free(dic);
        dic = NULL;
        dat = NULL;
        anz = 0;
    }
 
    UINT32 getlength(const char *archivename)
    {
        UINT32 i;
        for(i = 0; i < anz; i++)
        {
            if(!strcmp(dic[i].name, archivename))
                break;
        }
        if(i >= anz)
            return -1;
        return dic[i].len;
    }
 
    int readtofile(const char *filename, const char *archivename)
    {
        FILE *writefile;
        UINT32 len, i;
        char buf[1024];
        for(i = 0; i < anz; i++)
        {
            if(!strcmp(dic[i].name, archivename))
                break;
        }
        if(i >= anz)
            return 1;
        writefile = fopen(filename, "wb");
        if(writefile == NULL)
            return 2;
        fseek(dat, dic[i].off, SEEK_SET);
        len = dic[i].len;
        while(len > 1024)
        {
            fread(buf, 1, 1024, dat);
            fwrite(buf, 1, 1024, writefile);
            len -= 1024;
        }
        fread(buf, 1, len, dat);
        fwrite(buf, 1, len, writefile);
        fclose(writefile);
        return 0;
    }
 
    int readbytes(char *bytes, UINT32 maxbytelen, const char *archivename)
    {
        UINT32 i;
        for(i = 0; i < anz; i++)
        {
            if(!strcmp(dic[i].name, archivename))
                break;
        }
        if(i >= anz)
            return 1;
        if(dic[i].len < maxbytelen)
            maxbytelen = dic[i].len;
        fread(bytes, 1, maxbytelen, dat);
        return 0;
    }
};
 
int main()
{
	multifile_save speicherer;
  speicherer.open("beide.xyz");
  speicherer.addfromfile("a.jpg", "a");
  speicherer.addfromfile("b.png", "b");
  speicherer.close();
  return 0;
}
Danke
PS Auch wenn ich speicher.close() wegglasse kommt die gleiche debugger meldung
 
Zuletzt bearbeitet von einem Moderator:
Hi.

Du solltest versuchen den Code zu verstehen.

PS Auch wenn ich speicher.close() wegglasse kommt die gleiche debugger meldung
Das ist klar, da close() spätestens im Destruktor automatisch aufgerufen wird.

Dann sollte man vermeiden zuviel zu casten, da hätte einem der Compiler den Code schon um die Ohren geworfen:
C++:
fwrite(&anz, sizeof(anz), 1, dat);

Außerdem ist fast keine Fehlerprüfung in dem Code drin. Das solltest du noch anpassen.

Weiterhin frage ich mich: wieso so kompiliziert? In C++ geht das doch einfacher.

Gruß
 
Hi

jetzt auch getestet und korrigiert.

Wenn du das close beim Speichern "weglässt" wird es trotzdem im Destruktor gemacht.
Hätte also nicht wirklich was gebracht.
Außerdem icst es wichtig. Nicht nur zum ordentlichen Schließen, sondern weil da noch die Namen/Offsets/Längen der Dateien reingeschrieben werden müssen.
Ohne dem kann multifile_load nichts damit anfangen.

Und weil der Einfachkeit zuliebe nicht kontrolliert wird, ob die angegebene Datei wirklich von multifile_save erstellt wurde, werden witzige Probleme auftreten.

Also nicht zm Ausprobieren irgendeine Datei zum loaden angeben, die eigentlich was ganz anderes ist. Mit etwas Pech machts dann GB-weise Mülldaten.

C++:
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <malloc.h>
#include <windows.h>

struct multifile_fentry
{
	char name[256];
	UINT32 len, off;
};

class multifile_save
{
protected:

	struct multifile_fentry *dic;
	UINT32 anz;
	FILE *dat;

	multifile_save(multifile_save &x) {}
	multifile_save &operator=(multifile_save &x) { return *this; }

public:
	multifile_save()
	{
		dat = NULL;
		dic = NULL;
		anz = 0;
	}
	~multifile_save()
	{
		close();
	}

	int open(const char *destfile)
	{
		dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * 0);
		anz = 0;
		if(dic == NULL)
			return 1;
		dat = fopen(destfile, "wb");
		if(dat == NULL)
		{
			free(dic);
			return 2;
		}
		return 0;
	}

	void close()
	{
		if(dat != NULL)
		{
			fwrite((void *)dic, sizeof(multifile_fentry), anz, dat);
			fwrite((void *)(&anz), 4, 1, dat);
			fclose(dat);
			free(dic);
			dic = NULL;
			dat = NULL;
			anz = 0;
		}
	}

	int addfromfile(const char *filename, const char *archivename)
	{
		FILE *readfile;
		UINT32 len;
		char buf[1024];
		if(strlen(archivename) > 255)
			return 1;
		readfile = fopen(filename, "rb");
		if(readfile == NULL)
			return 2;
		if((anz % 20) == 0)
		{
			struct multifile_fentry *dic2;
			UINT32 j;
			dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
			if(dic2 == NULL)
			{
				fclose(readfile);
				return 3;
			}
			for(j = 0; j < anz; j++)
			{
				dic2[j].len = dic[j].len;
				dic2[j].off = dic[j].off;
				strcpy(dic2[j].name, dic[j].name);
			}
			free(dic);
			dic = dic2;
		}
		dic[anz].off = ftell(dat);
		len = filelength(fileno(readfile));
		dic[anz].len = len;
		strcpy(dic[anz].name, archivename);
		anz++;
		while(len > 1024)
		{
			fread(buf, 1, 1024, readfile);
			fwrite(buf, 1, 1024, dat);
			len -= 1024;
		}
		fread(buf, 1, len, readfile);
		fwrite(buf, 1, len, dat);
		fclose(readfile);
		return 0;
	}

	int addbytes(const char *bytes, UINT32 bytelen, const char *archivename)
	{
		if(strlen(archivename) > 255)
			return 1;
		if((anz % 20) == 0)
		{
			struct multifile_fentry *dic2;
			UINT32 j;
			dic2 = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * (anz + 20));
			if(dic2 == NULL)
				return 3;
			for(j = 0; j < anz; j++)
			{
				dic2[j].len = dic[j].len;
				dic2[j].off = dic[j].off;
				strcpy(dic2[j].name, dic[j].name);
			}
			free(dic);
			dic = dic2;
		}
		dic[anz].off = ftell(dat);
		dic[anz].len = bytelen;
		strcpy(dic[anz].name, archivename);
		anz++;
		fwrite(bytes, 1, bytelen, dat);
		return 0;
	}
};

class multifile_load
{
protected:

	struct multifile_fentry *dic;
	UINT32 anz;
	FILE *dat;

	multifile_load(multifile_load &x) {}
	multifile_load &operator=(multifile_load &x) { return *this; }

public:
	multifile_load()
	{
		dat = NULL;
		dic = NULL;
		anz = 0;
	}
	~multifile_load()
	{
		close();
	}

	int open(const char *sourcefile)
	{
		dat = fopen(sourcefile, "rb");
		if(dat == NULL)
			return 1;
		fseek(dat, -4, SEEK_END);
		fread((void *)(&anz), 4, 1, dat);
		dic = (struct multifile_fentry *)malloc(sizeof(multifile_fentry) * anz);
		if(dic == NULL)
		{
			fclose(dat);
			return 2;
		}
		fseek(dat, -4 - (sizeof(multifile_fentry) * anz), SEEK_END);
		fread((void *)dic, sizeof(multifile_fentry), anz, dat);
		return 0;
	}

	void close()
	{
		if(dat != NULL)
		{
			fclose(dat);
			free(dic);
			dic = NULL;
			dat = NULL;
			anz = 0;
		}
	}

	UINT32 getlength(const char *archivename)
	{
		UINT32 i;
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return -1;
		return dic[i].len;
	}

	int readtofile(const char *filename, const char *archivename)
	{
		FILE *writefile;
		UINT32 len, i;
		char buf[1024];
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return 1;
		writefile = fopen(filename, "wb");
		if(writefile == NULL)
			return 2;
		fseek(dat, dic[i].off, SEEK_SET);
		len = dic[i].len;
		while(len > 1024)
		{
			fread(buf, 1, 1024, dat);
			fwrite(buf, 1, 1024, writefile);
			len -= 1024;
		}
		fread(buf, 1, len, dat);
		fwrite(buf, 1, len, writefile);
		fclose(writefile);
		return 0;
	}

	int readbytes(char *bytes, UINT32 maxbytelen, const char *archivename)
	{
		UINT32 i;
		for(i = 0; i < anz; i++)
		{
			if(!strcmp(dic[i].name, archivename))
				break;
		}
		if(i >= anz)
			return 1;
		if(dic[i].len < maxbytelen)
			maxbytelen = dic[i].len;
		fread(bytes, 1, maxbytelen, dat);
		return 0;
	}
};

int main()
{
	return 0;
}

Gruß
 
Danke @deepthroat leider konnte ich den Code noch nicht durchlesen weil ich kein pc hatte konte nur ganz kurz testen.
Und an den Destruktur ahbe ich nicht gedacht :D
@sheel Danke ich werds jetzt testen....

EDIT: SO getestet funktioniert alles lesen schreiben und noch ein Frage an deepthroat bei dem aktuellen qullcode müssen da noch fehlerbehebungen rein?

Danke MFG
 
Zuletzt bearbeitet:
Um sicher zu gehen wärs nicht schlecht.
Die am häufigsten auftretenden Fehler (wie zB. eine nicht existierende Datei bei fopen) werden zwar geprüft, aber...wenn man es wirklich genau machen will, kann man so ziemlich jeden Funktionsaufruf auf irgendwelche Fehler abfragen.

edit: Auf die Schnelle durchgeschaut könnten folgende Funktionen noch Abfragen vertragen:
fwrite
fread
ftell
fseek
filenegth
fileno
fclose

Also so ca. alle Dateifunktionen außer Öffnen :D
 
Zuletzt bearbeitet:
Zurück