Kilka plików w jednym pliku

Odpowiedz Nowy wątek
2006-12-10 17:50
0

Jak w temacie. Powiedzmy, ze mam kilka obrazków w JPG, dzwięków i siatek 3DS i chciałbym je zapisać w jednym pliku, a potem odczytać za pomocą strumieni. Jest na to jakiś sposób? [???]


Pozostało 580 znaków

2006-12-10 18:05
0

oczywiście, że jest

Można to zrobić np. tak:

Zapisujesz do pliku tablicę np. array [0..25] of LongWord;
Element [0] będzie przechowywał informację o ilości plików znajdujących się w "bazie". Elementy [1..25] bedą przechowywały kolejne offstey położeń plików, po to aby móc je swobodnie wywoływać. Za tą tablicą dajesz już tylko pliki i po kłopocie.

// odczyt np. 19 pliku
AssignFile(F, '....');
Reset(F, 1);
Seek(F, Offsety[19]);
BlockRead(F, Bufor, Offsety[20]-Offsety[19]);

Mozna też użyć klasy TFileStram. Jak by co to pisz na gg. Nic nie stoi na przeszkodzie aby tablica info w pliku była rekordem, dodatkowo przechowującym nazwy plików.


<span style="color: blue">"Kolarstwo to jedna z najtrudniejszych dyscyplin sportu. Nawet najgorszy kolarz jest wciąż wybitnym sportowcem."
s.p. Marco Pantani
</span>

Pozostało 580 znaków

2006-12-11 01:36
0

zamiast kombinować jak koń pod górkę zainteresuj się strumieniami i poszukaj bo podawałem nawet dokładny kod jak zapisać i potem odczytać jpega i text chyba do jednego pliku


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-12-11 14:20
0

OLDFILE:=TFileStream.Create(sciezkapliku,fmOpenRead); //Plik źródłowy
NEWFILE :=TFileStream.Create(sciezkapliku2,fmOpenReadWrite); //Plik docelowy, musi istniec najlepiej stworzyc go gdzies wczesniej procedura rewrite, lub TFileStream.Create(sciezkapliku2,fmCreate);
NEWFILE.position:=NEWFILE.size

daneplikow.sposobdzielenia := 1024 //- tu musisz zapamietac ile bajtów pobierasz zeby potem przywrócic plik
daneplikow.rozmiarpliku:=OldFile.Size;
daneplikow.nazwapliku='Nazwa pliku'

// Proponuje daneplikow zapisac w jakims pliku rekordowym

daneplikow.liczbaoperacji:= (OldFile.Size div daneplikow.sposobdzielenia)
daneplikow.rozmiarosbuf:= (OldFile.Size mod daneplikow.sposobdzielenia)

for i:=1 to daneplikow.liczbaoperacji do
begin

                         SetLength(Buffer,daneplikow.sposobdzielenia);
                         oldfile.Read(Buffer[0],daneplikow.sposobdzielenia);
                         newfile.Write(Buffer[0] ,daneplikow.sposobdzielenia);
                         end;

oldfile.Read(Buffer[0],daneplikow.rozmiarosbuf);
newfile.Write(Buffer[0],daneplikow.rozmiarosbuf);

FreeAndNil(NewFile);
FreeAndNil(OldFile);

write(Plikzdanymi,daneplikow);

I po krzyku analogicznie robisz wyodrebniacza :)

Pozostało 580 znaków

2006-12-18 20:29
0

Sorki za późną odpowiedź, ale mialem troche szkoły.

Misiekd napisał(a)

(...) poszukaj bo podawałem nawet dokładny kod jak zapisać i potem odczytać jpega i text chyba do jednego pliku

Gdybym to znalazł to nie było by tematu [glowa]

A wracając do tematu, to napisałem takie dwa programiki:

  1. Zapisywanie do jednego pliku: (podam tylko procedure, która zbiera pliki z listbox'a i zapisuje do pliku o nazwie w Edit1.Text):

    procedure TForm1.Button3Click(Sender: TObject);
    const
    sposobdzielenia = 1024;
    var
    wynik: TFileStream;
    inne: array of TFileStream;
    licznik, l2: integer;
    temp1: integer;
    temp2: int64;
    s: ShortString;
    buffer: array of Char;
    dl, ilosc: integer;
    begin
    if (ListBox1.Items.Count = 0) then
    raise Exception.Create('Nie wybrano plików');
    wynik := TFileStream.Create(edit1.Text, fmCreate);
    SetLength(inne, ListBox1.Items.Count);
    temp1 := ListBox1.Items.Count;
    wynik.Write(temp1, SizeOf(temp1));
    for licznik := 0 to ListBox1.Items.Count - 1 do
    begin
    inne[licznik] := TFileStream.Create(ListBox1.Items.Strings[licznik], fmOpenRead);
    temp2 := inne[licznik].Size;
    wynik.Write(temp2, SizeOf(temp2));
    s := ExtractFileName(ListBox1.Items.Strings[licznik]);
    wynik.Write(s, SizeOf(s));
    end;
    for licznik := 0 to ListBox1.Items.Count - 1 do
    begin
    ilosc := inne[licznik].Size div sposobdzielenia;
    dl := inne[licznik].Size mod sposobdzielenia;
    for l2 := 0 to ilosc do
    begin
      SetLength(buffer, sposobdzielenia);
      inne[licznik].Read(buffer[0], sposobdzielenia);
      wynik.Write(buffer[0], sposobdzielenia);
    end;
    inne[licznik].Read(buffer[0], dl);
    wynik.Write(buffer[0], dl);
    inne[licznik].Free;
    end;
    
    wynik.Free;
    end;
  2. Wyodrębniacz:

    procedure TForm1.Button1Click(Sender: TObject);
    const
    sposobdzielenia = 1024;
    var
    strumien: TFileStream;
    licznik, ile, l2: integer;
    rozmiary: array of int64;
    nazwy: array of Shortstring;
    pliki: array of TFileStream;
    ilosc, dl: integer;
    buffor: array of char;
    begin
    if not (FileExists(edit1.Text)) then
    raise Exception.Create('Nieodnaleziono pliku!');
    strumien := TFileStream.Create(Edit1.Text, fmOpenRead);
    strumien.Read(ile, SizeOf(ile));
    SetLength(rozmiary, ile);
    SetLength(nazwy, ile);
    for licznik := 0 to ile - 1 do
    begin
    strumien.Read(rozmiary[licznik], SizeOf(rozmiary[licznik]));
    strumien.Read(nazwy[licznik], SizeOf(nazwy[licznik]));
    ListBox1.Items.Add(nazwy[licznik]);
    end;
    SetLength(pliki, ile);
    for licznik := 0 to ile - 1 do
    begin
    pliki[licznik] := TFileStream.Create(Edit2.Text + nazwy[licznik], fmCreate);
    dl := (rozmiary[licznik] mod sposobdzielenia);
    ilosc := (rozmiary[licznik] div sposobdzielenia);
    if (ilosc > 0) then
    for l2 := 1 to ilosc do
    begin
      SetLength(buffor, sposobdzielenia);
      strumien.Read(buffor[0], sposobdzielenia);
      pliki[licznik].Write(buffor[0], sposobdzielenia);
    end;
    strumien.Read(buffor[0], dl);
    pliki[licznik].Write(buffor[0], dl);
    pliki[licznik].Free;
    end;
    strumien.Free;
    nazwy := nil;
    rozmiary := nil;
    ShellExecute(application.Handle, 'open', PChar(Edit2.Text), nil, nil, SW_SHOWNORMAL);
    end;

    I jest jeden problem, a mianowicie po "wypakowaniu" plików tylko pierwszy jest zapisany prawidłowo, a kolejne już nie. Ich rozmiary są dokładnie takie same jak u źródeł. Ma kto jakiś pomysł?


Pozostało 580 znaków

2006-12-19 03:05
0

POKASUJ SWOJE DUPLIKATY!!

zapis

var
  InS, OutS: TFileStream;
  i, Len: Integer;
  FName: string;
begin
  OutS := TFileStream.Create('Out name', fmCreate); //stworzenie wyjściowego
  try
    for i := 0 to ListBox1.Items.Count - 1 do
    begin
      InS := TFileStream.Create(ListBox1.Items.Strings[licznik], fmOpenRead); //odczytanie pliku
      try
        FName := ExtractFileName(ListBox1.Items.Strings[licznik]); //pobranie nazwy pliku
        Len := Length(FName); //pobranie długości nazwy
        OutS.Write(Len, SizeOf(Len)); //zapisanie długości nazwy
        OutS.Write(Pointer(FName)^, Len); //zapisanie nazwy
        OutS.Write(InS.Size, SizeOf(InS.Size)); //zapisanie długości pliku
        OutS.CopyFrom(InS, 0); //zapisanie pojedyńczego pliku do "archiwum"
      finally
        FreeAndNil(InS);
      end;
    end;
  finally
    FreeAndNil(OutS);
  end;
end;

odczyt

var
  InS, OutS: TFileStream;
  Len: Integer;
  Size: Int64;
  FName: string;
begin
  InS := TFileStream.Create('In name', fmOpenRead); //otwarcie "spakowanego" pliku
  try
    while InS.Position < InS.Size do
    begin
      InS.Read(Len, SizeOf(Len); //odczytanie długości nazwy
      SetString(FName, nil, Len); //przygotowanie bufora do odczytania nazwy
      InS.Read(Pointer(FName)^, Len); //odczytanie nazwy
      InS.Read(Size, SizeOf(Size); //odczytanie wielkości pliku
      OutS := TFileStream.Create(FName, fmCreate); //stworzenie pliku
      try
        OutS.CopyFrom(InS, Size); //przekopiowanie pojedyńczego pliku
      finally
        FreeAndNil(OutS);
      end;
    end;
  finally
    FreeAndNil(InS);
  end;
end;

pisane z palca, ale na 99,9% będzie działać

dodatkowo przy użyciu ZLibEx możesz pakować "w locie" dodawane pliki i rozpokowywać je przy wyodrębnianiu. ZLibEx działa na strumieniach więc nie powinno być problemów


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-12-19 18:45
0

Kilka poprawek i działa. Wielkie dzięki za wszystkie odpowiedzi. [browar]


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0