UTL_COMPRESS Архивирование нескольких BLOB-объектов

Пожалуйста, кто-нибудь может мне помочь с информацией. В приведенном ниже коде для архивирования нескольких файлов мы используем несколько индексов. Можете ли вы указать, почему используются эти конкретные индексы:

  1. little_endian( t_clen - 18 ) - Почему 18 прошло здесь?

  2. for CRC32 : dbms_lob.substr( t_blob, 4, t_clen - 7 ) - Почему 4 и 7 пройдены здесь?

  3. dbms_lob.append( p_zipped_blob, dbms_lob.substr( t_blob, t_clen - 18, 11 ) ); -- compressed content - Почему 11 прошло здесь?

  4. И другие индексы, используемые в коде, такие как: 26,30,32 и т. Д.?


declare
  g_zipped_blob blob;
  b_dl_file1 BLOB;
  b_dl_file2 BLOB;
  b_dl_file3 BLOB;
-
  function little_endian( p_big in number, p_bytes in pls_integer := 4 )
  return raw
  is
  begin
    return utl_raw.substr( utl_raw.cast_from_binary_integer( p_big, utl_raw.little_endian ), 1, p_bytes );
  end;
--
  procedure add1file
    ( p_zipped_blob in out blob
    , p_name in varchar2
    , p_content in blob
    )
  is
    t_now date;
    t_blob blob;
    t_clen integer;
  begin
    t_now := sysdate;
    t_blob := utl_compress.lz_compress( p_content );
    t_clen := dbms_lob.getlength( t_blob );
    if p_zipped_blob is null
    then
      dbms_lob.createtemporary( p_zipped_blob, true );
    end if;
    dbms_lob.append( p_zipped_blob
                   , utl_raw.concat( hextoraw( '504B0304' ) -- Local file header signature
                                   , hextoraw( '1400' )     -- version 2.0
                                   , hextoraw( '0000' )     -- no General purpose bits
                                   , hextoraw( '0800' )     -- deflate
                                   , little_endian( to_number( to_char( t_now, 'ss' ) ) / 2
                                                  + to_number( to_char( t_now, 'mi' ) ) * 32
                                                  + to_number( to_char( t_now, 'hh24' ) ) * 2048
                                                  , 2
                                                  ) -- File last modification time
                                   , little_endian( to_number( to_char( t_now, 'dd' ) )
                                                  + to_number( to_char( t_now, 'mm' ) ) * 32
                                                  + ( to_number( to_char( t_now, 'yyyy' ) ) - 1980 ) * 512
                                                  , 2
                                                  ) -- File last modification date
                                   , dbms_lob.substr( t_blob, 4, t_clen - 7 )         -- CRC-32
                                   , little_endian( t_clen - 18 )                     -- compressed size
                                   , little_endian( dbms_lob.getlength( p_content ) ) -- uncompressed size
                                   , little_endian( length( p_name ), 2 )             -- File name length
                                   , hextoraw( '0000' )                               -- Extra field length
                                   , utl_raw.cast_to_raw( p_name )                    -- File name
                                   )
                   );
    dbms_lob.append( p_zipped_blob, dbms_lob.substr( t_blob, t_clen - 18, 11 ) );     -- compressed content
    dbms_lob.freetemporary( t_blob );
  end;
--
  procedure finish_zip( p_zipped_blob in out blob )
  is
    t_cnt pls_integer := 0;
    t_offs integer;
    t_offs_dir_header integer;
    t_offs_end_header integer;
    t_comment raw(32767) := utl_raw.cast_to_raw( 'Implementation by Anton Scheffer' );
  begin
    t_offs_dir_header := dbms_lob.getlength( p_zipped_blob );
    t_offs := dbms_lob.instr( p_zipped_blob, hextoraw( '504B0304' ), 1 );
    while t_offs > 0
    loop
      t_cnt := t_cnt + 1;
      dbms_lob.append( p_zipped_blob
                     , utl_raw.concat( hextoraw( '504B0102' )      -- Central directory file header signature
                                     , hextoraw( '1400' )          -- version 2.0
                                     , dbms_lob.substr( p_zipped_blob, 26, t_offs + 4 )
                                     , hextoraw( '0000' )          -- File comment length
                                     , hextoraw( '0000' )          -- Disk number where file starts
                                     , hextoraw( '0100' )          -- Internal file attributes
                                     , hextoraw( '2000B681' )      -- External file attributes
                                     , little_endian( t_offs - 1 ) -- Relative offset of local file header
                                     , dbms_lob.substr( p_zipped_blob
                                                      , utl_raw.cast_to_binary_integer( dbms_lob.substr( p_zipped_blob, 2, t_offs + 26 ), utl_raw.little_endian )
                                                      , t_offs + 30
                                                      )            -- File name
                                     )
                     );
      t_offs := dbms_lob.instr( p_zipped_blob, hextoraw( '504B0304' ), t_offs + 32 );
    end loop;
    t_offs_end_header := dbms_lob.getlength( p_zipped_blob );
    dbms_lob.append( p_zipped_blob
                   , utl_raw.concat( hextoraw( '504B0506' )                                    -- End of central directory signature
                                   , hextoraw( '0000' )                                        -- Number of this disk
                                   , hextoraw( '0000' )                                        -- Disk where central directory starts
                                   , little_endian( t_cnt, 2 )                                 -- Number of central directory records on this disk
                                   , little_endian( t_cnt, 2 )                                 -- Total number of central directory records
                                   , little_endian( t_offs_end_header - t_offs_dir_header )    -- Size of central directory
                                   , little_endian( t_offs_dir_header )                        -- Relative offset of local file header
                                   , little_endian( nvl( utl_raw.length( t_comment ), 0 ), 2 ) -- ZIP file comment length
                                   , t_comment
                                   )
                   );
  end;
--
  procedure save_zip
    ( p_zipped_blob in blob
    , p_dir in varchar2 := 'MY_DIR'
    , p_filename in varchar2 := 'my.zip'
    )
  is
    t_fh utl_file.file_type;
    t_len pls_integer := 32767;
  begin
    t_fh := utl_file.fopen( p_dir, p_filename, 'wb' );
    for i in 0 .. trunc( ( dbms_lob.getlength( p_zipped_blob ) - 1 ) / t_len )
    loop
      utl_file.put_raw( t_fh, dbms_lob.substr( p_zipped_blob, t_len, i * t_len + 1 ) );
    end loop;
    utl_file.fclose( t_fh );
  end;
begin
select FILE_BLOB
into b_dl_file1
from FILES
where FILE_ID = 64;

select FILE_BLOB
into b_dl_file2
from FILES
where FILE_ID = 65;

select FILE_BLOB
into b_dl_file3
from FILES
where FILE_ID = 66;
  add1file( g_zipped_blob, 'test1.bin', b_dl_file1 );
  add1file( g_zipped_blob, 'test2.bin', b_dl_file2 );
  add1file( g_zipped_blob, 'test2.bin', b_dl_file3 );
  finish_zip( g_zipped_blob );
  save_zip( g_zipped_blob, 'MY_DIR', 'my.zip' );
end;

0 ответов

Другие вопросы по тегам