Reîncarnarea datelor din câmpurile de memorie ii

Începând cu cel de-al 513-lea octet de la începutul fișierului, există blocuri de date. Valoarea câmpului poate ocupa unul sau mai multe blocuri. Fiecare bloc, care este primul pentru scriere, conține un antet de 8 octeți (4 octeți semnătura 0x00000001 și 4 octeți - lungimea câmpului), urmată de datele reale.







Pentru a asigura conectarea tabelului cu datele din fișierul fpt, ​​10 octeți sunt alocați câmpului de memorie din fiecare înregistrare a fișierului dbf, în care este introdus numărul primului bloc de date. Și numărul este stocat într-o formă simbolică cu spații de conducere. De exemplu, pentru a indica blocul 8, acest câmp va conține valoarea "8" (în hexazecimal "20 20 20 20 20 20 20 20 20 38", unde 38 este codul ASCII al simbolului "8"). Numerotarea blocurilor merge de la începutul fișierului, adică include antetul.

De exemplu, atunci când lungimea blocului standard 64 octeți de date de înregistrare va începe la blocul 8 (lungimea antet 512, mărimea blocului împărțit la 64).

Cu ce ​​este necesar să lupți

Teoretic, formatul DBF permite stocarea a până la 4 GB de date într-un câmp de tip memo. Cu toate acestea, în practică, datorită limitărilor interne ale FoxPro asupra lungimii liniei, este dificil să operezi cu câmpuri de peste 65504 de caractere. În practică, lungimea acestui câmp rareori depășește câteva mii de caractere. Prin urmare, este perfect permis să presupunem că datele dintr-un câmp de tip memo pot fi plasate în câmpul text al tabelului PostgreSQL (valoarea maximă a câmpului este de 1 Gb). Deci dimensiunea câmpurilor nu va fi considerată o problemă.

Mai dificil este că câmpurile de memorie pot conține o varietate de caractere, inclusiv un caracter nou. Din moment ce PostgreSQL tratează acest text ca un delimitator de înregistrare atunci când procesează un fișier text, trebuie să aveți grijă să îl vizualizați. Și în cazul sfârșitul formatului liniei de DOS-stil (CR + LF) screening-ul este necesar ca newline (0x0D), și cu un caracter retur de car (0x0A).

Implementare pe FoxPro

FoxPro lucrează cu câmpuri de memorie în mod transparent, astfel încât nu este nevoie de efort din partea programatorului. Nu uitați să plasați caracterul "" înainte de caracterele de delimitare:

Listing 1. Fișierul memo2pg.prg (FoxPro)

folosiți wmem Deschideți tabelul cu câmpuri de memorie

m.delimiter = chr (9) cartea de caractere

* Câmp text - delimitatori de ecran și caracterul "\"







m.descr = strtran (m.descr, m.delimiter;

* În câmpul de memorie, vom afișa în plus caracterele de la sfârșitul liniei (codurile ASCII 10 și 13)

m.memfld = strtran (m.memfld, m.delimiter;

m.memfld = strtran (m.memfld, chr (13) ,;

m.memfld = strtran (m.memfld, chr (10) ,;

* Scrie rezultatul într-un fișier, separând câmpurile cu simbolul stocat în variabila m.delimiter

fereastră de așteptare "Terminat".

Figura. Fereastra de lucru FoxPro

Dacă decideți să lucrați cu un CSV format, în locul filei ca separator este o virgulă, și fiecare câmp de date, indiferent de tipul, va trebui să înconjoare simvolom- „citat“, cum ar fi „““, care este implicit. În interiorul câmpurilor, toate "citatele" ar trebui dublate pentru a exclude interpretarea lor specială.

Implementarea în Python

Și aici trebuie să aplicăm toate cunoștințele acumulate la formatul fișierelor DBF și FPT. Deoarece scriptul complet pentru parsarea fișierului DBF a fost citat în ultimul articol, aici ne limităm doar la partea care este responsabilă pentru obținerea datelor din câmpul memo. Scriptul se bazează pe scriptul dbf2pg.py, discutat în articolul precedent (a se vedea Listing 2). A adăugat procesarea câmpurilor tip "M" într-un ciclu care procesează fiecare înregistrare (liniile corespunzătoare sunt evidențiate în roșu):

Listarea 2. Fragmentul scriptului dbf2pg.py, adăugate linii

pentru i în intervalul (num):

dacă câmpurile [i] .type == 'M':

dacă câmpurile [i] .type == 'D':

fld = fld [: 4] + '-' + fld [4: 6] + '- fld [6:]

Aici, atunci când detectează valoarea citită tip de câmp memo este tratată ca cuprinzând un număr al primului bloc de date, iar funcția se numește parsarea FPT-fișier:

Listă 3. Fragmentul scriptului dbf2pg.py, funcția memo2pg

# Numărul blocului este convertit la un număr

fpt = deschis (numele bazei de date + '.fpt', 'rb')

# Citiți dimensiunea blocului

blockize = int (ord (fpt.read (1)) * 256 + ordin (fpt.read (1)))

# Mutați la începutul blocului de date

# Citiți dimensiunea câmpului de date

fieldsize = ord (fpt.read (1)) * 16777216 + ord (fpt.read (1)) * 65536 + ord (fpt.read (1)) * 256 + ord (fpt.read (1))

# Transcoding, screening și așa mai departe.

data = unicode (date, 'cp866') codifica ('koi8-r')

date = data.replace ('\ x0A', '\\' + '\ x0A')

date = data.replace ('\ x0D', '\\' + '\ x0D')

data = data.replace (delimiter, '\\' + delimiter)

În cele din urmă, trebuie să aibă grijă, deschise în modul binar, și pentru a forma sfârșitul șirului Python nu este procesat rânduri noi te de ce în loc să afișeze fiecare linie format dintr-o declarație de imprimare, vom scrie la fișierul manual, așa cum avem nevoie de:

Listarea 4. Fragmentul scriptului dbf2pg.py, scriind o linie într-un fișier

Ca urmare, dbf2pg.py poate, de asemenea, procesa câmpurile memorate.

Limba FoxPro oferă instrumente avansate pentru lucrul cu fișierele (ar arata ciudat daca nu era), și să efectueze conversia fișierelor DBF într-un alt format de c înseamnă - este câteva linii de cod. Cu toate acestea, nu contează dacă nu sunteți foarte prietenos cu el sau nu îl puteți folosi din vreun motiv. Formatul binar DBF, după cum puteți vedea, este simplu și convenabil. Deci, dacă este necesar, nu va fi posibilă implementarea prelucrării sale cu mijloacele de muncă disponibile.







Articole similare

Trimiteți-le prietenilor: