powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Чтение больших csv в базу
25 сообщений из 33, страница 1 из 2
Чтение больших csv в базу
    #39528216
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброе время суток,

нужно периодически заливать в базу пару больших csv (около 1.5 гиг).
csvDocument с такими работать не умеет. Можно сваять что то своё на осноте TMemoryStream но зачем изобретать велосипед, наверняка есть уже что то готовое?

Спасибо
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528236
sql2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenko,

СУБД (какая?) не поддерживает импорт?
или написать построчное чтение... не вариант?
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528241
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenko наверняка есть уже что то готовое?


Readln
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528245
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sql2012Mikhail Tchervonenko,

СУБД (какая?) не поддерживает импорт?
или написать построчное чтение... не вариант?
FB 3
Попробовал через импорт IBExpert, тоже отвалился с исключением.

Есть готовый скрипт построчного чтения с разбором?
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528247
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiMikhail Tchervonenko наверняка есть уже что то готовое?


Readln
да оно понятно что можно и так, думал может что то готовое есть что не пихает всё сразу в память
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528252
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Mikhail Tchervonenkoschiпропущено...


Readln
да оно понятно что можно и так, думал может что то готовое есть что не пихает всё сразу в память
ну так readln и не пихает всё в память
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528256
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorMikhail Tchervonenkoпропущено...

да оно понятно что можно и так, думал может что то готовое есть что не пихает всё сразу в память
ну так readln и не пихает всё в память
да, но и буферизацию толком не делает. Наверняка медленно будет.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528261
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mikhail Tchervonenko,

Посмотри подключение внешних файлов, делал приблизительно тоже самое, только у меня DBF был
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528268
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528270
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenkoно и буферизацию толком не делает

есть такая функция, SetTextBuf

но вообще - да, readLn сделан под чтение нескольких переменных с одной строки
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528272
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528275
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528285
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenkodefecatorпропущено...

ну так readln и не пихает всё в память
да, но и буферизацию толком не делает. Наверняка медленно будет.

На удивление нет.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528288
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenkoschiпропущено...


Readln
да оно понятно что можно и так, думал может что то готовое есть что не пихает всё сразу в память
Есть готовое:

1. Читаешь строку: Readln.
2. Парсишь CSV: TStringList.DelimetedText := <Строка>
3. Заливаешь в базу
4. Смыть, повторить.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528310
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ок, всем спасибо за участие.
Примерно понял состояние дел.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528327
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenkoдумал может что то готовое есть что не пихает всё сразу в память

http://www.ibphoenix.com/products/software/dbfile
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528352
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Часть тестового задания по многопоточной сортировке, в т.ч. и для работы с файлами больше 4гб:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
unit myStrUtils;

interface

uses Windows, Classes, SysUtils;

resourcestring
    SFCreateErrorEx = 'Cannot create file "%s". %s';
    SFOpenErrorEx   = 'Cannot open file "%s". %s';

const
    KB = Int64(1024);
    MB = 1024*KB;
    GB = 1024*MB;

    DEFAULT_BUFSIZE = 16*MB;
    MIN_BUFSIZE     = KB;
    MAX_BUFSIZE     = 16*MB;

type
    BigInt = Int64;
    TBufferedFileStream = class(TStream)
    private
        FHandle     : BigInt;
        FFileSize   : BigInt;
        FFileOffset : BigInt;
        FBuf        : PByte;
        FBufSize    : BigInt;
        FBufCount   : BigInt;
        FBufPos     : BigInt;
        FDirty      : Boolean;
        function GetPosition: Int64;
        procedure SetPosition(const Value: Int64);

    protected
        procedure   SetSize(const NewSize: Int64); override;
        function    GetFileSize: BigInt;
        procedure   Init(BufSize: BigInt);
        procedure   ReadFromFile;
        procedure   WriteToFile;
    public
        constructor Create(const FileName: string; Mode: Word; BufferSize: BigInt); overload;
        constructor Create(const FileName: string; Mode: Word; Rights: Cardinal; BufferSize: BigInt); overload;
        destructor  Destroy; override;

        procedure   Flush;
        function    BigRead(var Buffer; Count: BigInt): BigInt; overload;

        function    BigSeek(Offset: BigInt; Origin: Word): BigInt; overload;
        function    BigSeek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload;
        function    BigWrite(const Buffer; Count: BigInt): BigInt; overload;
        property    FastSize : BigInt read FFileSize;
        property    Position: Int64 read GetPosition write SetPosition;
    end;

    TCustomList = class(TList)
    private
        function GetStringItem(index: integer): AnsiString;
        function GetItemLength(index: integer): integer;
    protected
        FFromPos: Int64;
        FCurrentItemSize: integer;
        FBuffer: Pointer;
        FLastItem: Pointer;
        FBufferSize: int64;
        FItemsSize: int64;
        FSorted: boolean;
        FCurrentItem: Pointer;
        FCurrentItemIndex: integer;
        FStream: TBufferedFileStream;
        procedure FreeBuffer;
        function AllocateBuffer(const NewSize: BigInt): boolean;
        procedure ClearBuffer;
        procedure ScanBuffer;
    public
        constructor Create; overload;
        destructor Destroy; override;
        function LoadFromStream(const Stream: TBufferedFileStream; const AFromPos, AMaxLength: Int64): Int64;
        function SaveToStream(const Stream: TBufferedFileStream; const AFromPos: Int64): Int64;
        procedure Sort; overload;
        function InitMergeList(const AFileName: string; const AMaxLength: int64): boolean;
        procedure First;
        function Next: boolean;
        property CurrentItem: pointer read FCurrentItem;
        property CurrentItemSize: integer read FCurrentItemSize;
        property StringItem[index: integer]: AnsiString read GetStringItem;
        property ItemLength[index: integer]: integer read GetItemLength;
        property FromPos: Int64 read FFromPos;
        property ItemsSize: Int64 read FItemsSize;
    end;

function CustomCompareBuffer(S1, S2: Pointer): Integer;
function CustomCompareList(S1, S2: Pointer): Integer;
function Min(const IntOne, IntTwo: BigInt): BigInt;
function MakeString(const APointer: Pointer; const ASize: integer): AnsiString;
function ScanBuf(const AByte: Byte; const APointer: Pointer): integer;

implementation

uses RTLConsts;

function Min(const IntOne, IntTwo: BigInt): BigInt;
begin
    if IntOne > IntTwo then
        Result := IntTwo
    else
        Result := IntOne;
end;

function MakeString(const APointer: Pointer; const ASize: integer): AnsiString;
begin
    SetLength(Result, ASize);
    if LongBool(ASize) then
        System.Move(APointer^, Result[1], ASize);
end;

function ScanBuf(const AByte: Byte; const APointer: Pointer): integer;
var i: integer;
    b: byte;
begin
    i := 0;
    repeat
        b := PByte(NativeInt(APointer)+i)^;
        if b = AByte then exit(i)
        else if b = 13 then break;
        inc(i);
    until false;
    result := -1;
end;

function CustomCompareBuffer(S1, S2: Pointer): Integer;
var i1, i2: integer;

    function CmpStr(const P1, P2: integer; const S1, S2: pointer): integer;
    var i, l1, l2: integer;
        b1, b2: integer;
    begin
        result := 0;
        i := 0;
        repeat
            b1 := PByte(NativeInt(S1)+P1+i)^;
            b2 := PByte(NativeInt(S2)+P2+i)^;
            result := b1 - b2;
            inc(i);
        until (result <> 0) or (b1 = 13) or (b2 = 13);
    end;

    function CmpInt(const P1, P2: integer; const S1, S2: pointer): integer;
    var i: integer;
    begin
        i := 0;
        result := P1 - P2;
        while (result = 0) and (i < P2) and (i < P1) do begin
            result := PByte(NativeInt(S1)+i)^-PByte(NativeInt(S2)+i)^;
            inc(i);
        end;
    end;

begin
    i1 := ScanBuf(Ord('.'), S1);
    i2 := ScanBuf(Ord('.'), S2);
    result := CmpStr(i1+2, i2+2, S1, S2);
    if result = 0 then
        result := CmpInt(i1, i2, S1, S2);
end;

function CustomCompareList(S1, S2: Pointer): Integer;
begin
    result := CustomCompareBuffer(TCustomList(S1).CurrentItem, TCustomList(S2).CurrentItem);
end;

{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TBufferedFileStream.Init(BufSize: BigInt);
begin
    FBufSize := BufSize;
    if FBufSize < MIN_BUFSIZE then
        FBufsize := MIN_BUFSIZE
    else
    if FBufSize > MAX_BUFSIZE then
        FBufSize := MAX_BUFSIZE
    else
    if (FBufSize mod MIN_BUFSIZE) <> 0 then
        FBufSize := DEFAULT_BUFSIZE;
    GetMem(FBuf, FBufSize);
    FFileSize   := GetFileSize;
    FBufCount   := 0;
    FFileOffset := 0;
    FBufPos     := 0;
    FDirty      := False;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TBufferedFileStream.Create(const FileName: string; Mode: Word;
    BufferSize: BigInt);
begin
    Create(Filename, Mode, 0, BufferSize);
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TBufferedFileStream.Create(const FileName : string; Mode: Word;
    Rights: Cardinal; BufferSize: BigInt);
begin
    inherited Create;
    FHandle := -1;
    FBuf    := nil;
    if Mode = fmCreate then
    begin
        FHandle := FileCreate(FileName, Mode, Rights);
        if FHandle < 0 then
            raise EFCreateError.CreateResFmt(@SFCreateErrorEx,
                                             [ExpandFileName(FileName),
                                             SysErrorMessage(GetLastError)]);
    end
    else begin
        FHandle := FileOpen(FileName, Mode);
        if FHandle < 0 then
            raise EFOpenError.CreateResFmt(@SFOpenErrorEx,
                                           [ExpandFileName(FileName),
                                           SysErrorMessage(GetLastError)]);
    end;
    Init(BufferSize);
end;

{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TBufferedFileStream.Destroy;
begin
    if (FHandle >= 0) then begin
        if FDirty then
            WriteToFile;
        FileClose(FHandle);
    end;
    if FBuf <> nil then
        FreeMem(FBuf, FBufSize);
    inherited Destroy;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TBufferedFileStream.GetFileSize: BigInt;
var
    OldPos : BigInt;
begin
    OldPos := FileSeek(FHandle, Int64(0), soFromCurrent);
    Result := FileSeek(FHandle, Int64(0), soFromEnd);
    FileSeek(FHandle, OldPos, soFromBeginning);
    if Result < 0 then
        raise Exception.Create('Cannot determine correct file size');
end;


function TBufferedFileStream.GetPosition: Int64;
begin
    Result := BigSeek(Int64(0), soCurrent);
end;

{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TBufferedFileStream.ReadFromFile;
var
    NewPos : BigInt;
begin
    NewPos := FileSeek(FHandle, FFileOffset, soFromBeginning);
    if (NewPos <> FFileOffset) then
        raise Exception.Create('Seek before read from file failed');
    FBufCount := FileRead(FHandle, FBuf^, FBufSize);
    if FBufCount = -1 then
        FBufCount := 0;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TBufferedFileStream.WriteToFile;
var
    NewPos : BigInt;
    BytesWritten : BigInt;
begin
    NewPos := FileSeek(FHandle, FFileOffset, soFromBeginning);
    if (NewPos <> FFileOffset) then
        raise Exception.Create('Seek before write to file failed');
    BytesWritten := FileWrite(FHandle, FBuf^, FBufCount);
    if (BytesWritten <> FBufCount) then
        raise Exception.Create('Could not write to file');
    FDirty := False;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TBufferedFileStream.Flush;
begin
    if FDirty and (FHandle >= 0) and (FBuf <> nil) then
        WriteToFile;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TBufferedFileStream.BigRead(var Buffer; Count: BigInt): BigInt;
var
    Remaining   : BigInt;
    Copied      : BigInt;
    DestPos     : BigInt;
begin
    Result := 0;
    if FHandle < 0 then Exit;
    Remaining := Min(Count, FFileSize - (FFileOffset + FBufPos));
    Result := Remaining;
    if (Remaining > 0) then
    begin
        if (FBufCount = 0) then
            ReadFromFile;
        Copied := Min(Remaining, FBufCount - FBufPos);
        Move(FBuf[FBufPos], TByteArray(Buffer)[0], Copied);
        Inc(FBufPos, Copied);
        Dec(Remaining, Copied);
        DestPos := 0;
        while Remaining > 0 do
        begin
            if FDirty then
                WriteToFile;
            FBufPos := 0;
            Inc(FFileOffset, FBufSize);
            ReadFromFile;
            Inc(DestPos, Copied);
            Copied := Min(Remaining, FBufCount - FBufPos);
            Move(FBuf[FBufPos], TByteArray(Buffer)[DestPos], Copied);
            Inc(FBufPos, Copied);
            Dec(Remaining, Copied);
        end;
    end;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TBufferedFileStream.BigWrite(const Buffer; Count: BigInt): BigInt;
var
    Remaining : BigInt;
    Copied    : BigInt;
    DestPos   : BigInt;
begin
    Result := 0;
    if FHandle < 0 then Exit;
    Remaining := Count;
    Result := Remaining;
    if (Remaining > 0) then begin
        if (FBufCount = 0) and ((FFileOffset + FBufPos) <= FFileSize) then
            ReadFromFile;
        Copied := Min(Remaining, FBufSize - FBufPos);
        Move(PByte(Buffer), FBuf[FBufPos], Copied);
        FDirty := True;
        Inc(FBufPos, Copied);
        if (FBufCount < FBufPos) then begin
            FBufCount := FBufPos;
            FFileSize := FFileOffset + FBufPos;
        end;
        Dec(Remaining, Copied);
        DestPos := 0;
        while Remaining > 0 do begin
            WriteToFile;
            FBufPos := 0;
            Inc(FFileOffset, FBufSize);
            if (FFileOffset < FFileSize) then
                ReadFromFile
            else
                FBufCount := 0;
            Inc(DestPos, Copied);
            Copied := Min(Remaining, FBufSize - FBufPos);
            Move(TByteArray(Buffer)[DestPos], FBuf[0], Copied);
            FDirty := True;
            Inc(FBufPos, Copied);
            if (FBufCount < FBufPos) then begin
                FBufCount := FBufPos;
                FFileSize := FFileOffset + FBufPos;
            end;
            Dec(Remaining, Copied);
        end;
    end;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TBufferedFileStream.BigSeek(Offset: BigInt; Origin: Word): BigInt;
begin
    Result := BigSeek(Int64(Offset), TSeekOrigin(Origin));
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TBufferedFileStream.BigSeek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var
    NewPos        : BigInt;
    NewFileOffset : BigInt;
begin
    Result := 0;
    if FHandle < 0 then Exit;

    if (Offset = 0) and (Origin = soCurrent) then begin
        Result := FFileOffset + FBufPos;
        Exit;
    end;

    case Origin of
        soBeginning : NewPos := Offset;
        soCurrent   : NewPos := (FFileOffset + FBufPos) + Offset;
        soEnd       : NewPos := FFileSize + Offset;
      else
        raise Exception.Create('Invalid seek origin');
    end;

    if (NewPos < 0) then
        NewPos := 0
    else
    if (NewPos > FFileSize) then
        FFileSize := FileSeek(FHandle, NewPos - FFileSize, soFromEnd);

    NewFileOffset := (NewPos div FBufSize) * FBufSize;

    if (NewFileOffset <> FFileOffset) then begin
        if FDirty then
            WriteToFile;
        FFileOffset := NewFileOffset;
        FBufCount := 0;
    end;
    FBufPos := NewPos - FFileOffset;
    Result  := NewPos;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TBufferedFileStream.SetPosition(const Value: Int64);
begin
    BigSeek(Int64(Value), soBeginning);
end;

procedure TBufferedFileStream.SetSize(const NewSize: Int64);
begin
    if FHandle < 0 then Exit;
    BigSeek(NewSize, soFromBeginning);
    if NewSize < FFileSize then
        FFileSize := FileSeek(FHandle, NewSize, soFromBeginning);
{$IFDEF MSWINDOWS}
    if not SetEndOfFile(FHandle) then
        RaiseLastOSError;
{$ELSE}
    if ftruncate(FHandle, Position) = -1 then
        raise EStreamError(sStreamSetSize);
{$ENDIF}
end;

{ TCustomList }

function TCustomList.AllocateBuffer(const NewSize: BigInt): boolean;
begin
    result := false;
    if LongBool(FBuffer) then begin
        if FBufferSize <> NewSize then begin
            FreeBuffer;
        end else
            exit(true);
    end;
    try
        GetMem(FBuffer, NewSize);
        FBufferSize := NewSize;
        result := true;
    except on E: EOutOfMemory do begin
        result := false;
    end;
    end;
end;

procedure TCustomList.ClearBuffer;
begin
    FSorted := false;
    FItemsSize := 0;
end;

constructor TCustomList.Create;
begin
    inherited;
end;

destructor TCustomList.Destroy;
begin
    FreeBuffer;
    if LongBool(FStream) then
        FStream.Free;
    inherited;
end;

procedure TCustomList.First;
begin
    FCurrentItem := FBuffer;
end;

procedure TCustomList.FreeBuffer;
begin
    FSorted := false;
    if LongBool(FBuffer) then begin
        FreeMem(FBuffer, FBufferSize);
        FBuffer := nil;
        FBufferSize := 0;
        FItemsSize := 0;
    end;
end;

function TCustomList.GetStringItem(index: integer): AnsiString;
begin
    Result := MakeString(items[index], ItemLength[index]);
end;

function TCustomList.InitMergeList(const AFileName: string; const AMaxLength: int64): boolean;
var pos: int64;
begin
    FreeBuffer;
    FStream := TBufferedFileStream.Create(AFileName, fmOpenRead+fmShareDenyWrite, 0);
    pos := LoadFromStream(FStream, -1, AMaxLength);
    result := pos > 0;
    if result then begin
        ScanBuffer;
        result := Next;
    end;
end;

function TCustomList.GetItemLength(index: integer): integer;
begin
    if (Index >=0) and (Index < Count) then begin
        if Items[index] = FLastItem then
            result := NativeInt(FBuffer)+FItemsSize-NativeInt(Items[index])
        else begin
            if FSorted then begin
                result := ScanBuf(13, Items[index])+2
            end else begin
                result := NativeInt(Items[index+1])-NativeInt(Items[index])
            end;
        end;
    end else
        Error(@SListIndexError, Index);
end;

function TCustomList.LoadFromStream(const Stream: TBufferedFileStream; const AFromPos, AMaxLength: Int64): Int64;
var CR: BigInt;
begin
    result := 0;
    FCurrentItem := nil;
    FCurrentItemIndex := 0;
    FCurrentItemSize := 0;
    if AllocateBuffer(AMaxLength) then begin
        if AFromPos <> -1 then
            Stream.BigSeek(AFromPos, soFromBeginning);
        result := Stream.BigRead(FBuffer^, FBufferSize);
        if result > 0 then begin
            cr := 0;
            while PByte(NativeInt(FBuffer)+result-cr)^ <> 10 do
                inc(cr);
            result := result-cr+1;
            Stream.BigSeek(-cr+1, soFromCurrent);
        end;
    end;
    FSorted := false;
    FFromPos := AFromPos;
    FItemsSize := result;
end;

function TCustomList.Next: boolean;
begin
    if FCurrentItem = FLastItem then begin
        result := LoadFromStream(FStream, -1, FBufferSize) > 0;
        if result then begin
            ScanBuffer;
            FCurrentItem := FBuffer;
            FCurrentItemSize := ItemLength[0];
        end else begin
            FCurrentItem := nil;
            FCurrentItemSize := 0;
        end;
    end else if LongBool(FCurrentItem) then begin
        inc(FCurrentItemIndex);
        FCurrentItem := Items[FCurrentItemIndex];
        FCurrentItemSize := ItemLength[FCurrentItemIndex];
        result := true;
    end else begin
        FCurrentItem := FBuffer;
        FCurrentItemSize := ItemLength[0];
        result := true;
    end;
    if not Result then
        FCurrentItemSize := 0;
end;

function TCustomList.SaveToStream(const Stream: TBufferedFileStream; const AFromPos: Int64): Int64;
var i: integer;
begin
    result := 0;
    Stream.BigSeek(AFromPos, 0);
    if FSorted then begin
        for I := 0 to Count-1 do
            Stream.BigWrite(Items[i]^, ItemLength[i]);
    end else begin
        Stream.BigWrite(FBuffer^, FItemsSize);
    end;
    FFromPos := AFromPos;
    result := Stream.Position - AFromPos;
end;

procedure TCustomList.ScanBuffer;
var StartIdx, EndIdx: bigInt;
begin
    Clear;
    if (not LongBool(FBuffer)) or (not LongBool(FItemsSize)) then exit;

    StartIdx := 0;
    EndIdx := 0;
    repeat
        if PByte(NativeInt(FBuffer)+EndIdx)^ = 13 then begin
            Add(PByte(NativeInt(FBuffer)+StartIdx));
            while (PByte(NativeInt(FBuffer)+EndIdx)^ in [10, 13])
                and (EndIdx < FItemsSize) do inc(EndIdx);
            StartIdx := EndIdx;
        end;
        inc(EndIdx);
    until EndIdx >= FItemsSize;
    if Count > 0 then
        FLastItem := Items[Count-1]
    else
        FLastItem := nil;
end;

procedure TCustomList.Sort;
begin
    ScanBuffer;
    if Count < 2 then exit;
    Sort(CustomCompareBuffer);
    FSorted := true;
end;

end.



После загрузки в list нужно вызвать scanbuffer и затем доставать строки через StringItem.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528354
Фотография Mikhail Tchervonenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

спасибо, это уже ближе к делу
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528356
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenkoэто уже ближе к делу
Ближе? Это дело целиком, на блюдечке.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528618
Мистер Шляпа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikhail Tchervonenko,

Может быть, посмотреть в сторону ETL? Datastage, Pentaho. В них есть готовые инструменты для подобных задач.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528713
Фотография Makar4ik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiMikhail Tchervonenko наверняка есть уже что то готовое?


Readlnненене.
есть fileopen
для таких тяжеляков надо работать на самом низком уровне.
И парсить CSV ручками, и без любых попыток использования дельфийского типа данных string

Везде - только PChar

...тогда, да, парсинг будет - почти со скоростью чтения с диска.
Проверено.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528714
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Makar4ik,

Не не не! У них ручки не разработанные. По этому уже существующий софт, и ничего из своих велосипедов.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528715
Фотография Makar4ik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикMakar4ik,

Не не не! У них ручки не разработанные. По этому уже существующий софт, и ничего из своих велосипедов.надо тренировать своё тело.
MFC познать например, или, понять как сортируют по Кнуту...

Ну, это шутки.
Но я правду сказал.
Нельзя обработать гигабайты стандартными консьюмерскими компонентами.
Надо самому моск включать.
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528716
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Makar4ikНельзя обработать гигабайты стандартными консьюмерскими компонентами.


Думаю, как и многим создателям своего софта, и в голову не приходило. Что кто - то будет грузить файлы в несколько гб

По этому, соглашусь
...
Рейтинг: 0 / 0
Чтение больших csv в базу
    #39528719
Фотография Makar4ik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикMakar4ikНельзя обработать гигабайты стандартными консьюмерскими компонентами.


Думаю, как и многим создателям своего софта, и в голову не приходило. Что кто - то будет грузить файлы в несколько гб

По этому, соглашусьнекоторым приходило.
Поэтому бывают маппинги файлов в память окнами.
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Чтение больших csv в базу
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]