Read 기능으로 대량의 Run Program을 처리하는 방법많은 양의 쉼표로 구분된 데이터를 콘솔에 인쇄하는 외부 응용 프로그램을 실행하려고 합니다. 출력은 기본적으로 .NET 응용 프로그램에서 가져온 큰 데이터 테이블입니다. "행"은 쉼표로 구분되며 각 행 다음에 줄 바꿈 문자가 옵니다. 첫 번째 행은 헤더이며 데이터 테이블은 헤더로 업데이트해야 합니다. 콘솔을 읽는 예제 코드를 따랐지만 일부 줄이 부분적으로 완료되는 문제가 발생했습니다(줄 바꿈에서 분리되지 않음). 그런 다음 부분 줄을 제거하고 다음 줄의 시작 부분에 추가하려고 하지만 여전히 몇 줄(4338개 중 ~35개)이 누락되었습니다. 프로그램이 완료되면 텍스트 변수에 쓰고 처리하면 작동하지만 훨씬 느립니다(아마도 문자열이 정말 길고 외부 응용 프로그램과 동시적이지 않기 때문일 수 있지만 그건 제 추측일 뿐입니다).
한 번에 전체 줄을 캡처할 수 있도록 읽기 기능이 호출되는 시기를 제어하는 방법이 있습니까? 이를 처리하는 알려진 방법이 있습니까?
.NET 소스 코드에 액세스할 수 있으며 필요한 경우 출력을 수정하여 JSL 친화적으로 만들 수 있습니다.
내 코드를 붙여넣고 민감한 열 이름을 "IDx"로 바꿉니다. 미리 감사드립니다!
results = Run Program(
Executable(myExecutable),
Options(options),
Read Function(Function({this},
fullValue = this << Read;
lines = Words( fullValue,"\!n" );
lineIndex = 1;
totalLines = totalLines + N Items(lines);
callCount++;
words = Words(lines[1], ",");
if (N Items(words) > 1,
if (extraContent != "", lines[1] = appendExtraContent(lines[1],extraContent),);
newExtraContent = getExtraContent(fullValue);
if (N Items(lines) == 1,
extraContent = extraContent || newExtraContent,
extraContent = newExtraContent
);
if (extraContent != "",
print(lines[NItems(lines)]);
Remove From(lines, N Items(lines));
extraLines++;,
);
if (N Items(lines) >= 1,
if (first == 1,
headers = Words(lines[1],",");
For (i = 14, i <= N Items(headers), i++,
dt << New Column(headers[i], Character);
);
headerCount++;
first = 0;
lineIndex++;
cols = dt << Get Column Names();,);
For( i = lineIndex, i <= N Items(lines), i++,
//print(lines[i]);
count++;
word = break_string_by_sep(lines[i], ",");
if ( N Items(word) > maxHeaders, maxHeaders = N Items(word),);
if (N Items(word) >= 14,
dt << Add Row({
:ID1 = word[1];
:ID2 = word[2];
:ID3 = Num(word[3]);
:ID4 = Num(word[4]);
:ID5 = word[5];
:ID6 = Num(word[6]);
:ID7 = word[7];
:ID8 = Num(word[8]);
:ID9 = word[9];
:ID10 = word[10];
:ID11 = Num(word[11]);
:ID12 = Num(word[12]);
:ID13 = Num(word[13]);
For (k = 14, k <= N Items(cols) , k++,
if (N Items(word) >= k,
AsColumn(dt,cols[k]) = word[k],
);
);
}),
);
);
,);
,);
);
)
);
While (!(results << Is Read EOF), Wait(1));
dt << ShowWindow(1);
);
appendExtraContent = Function({partialValue, extra}, {default local},
fullLine = extra || partialValue;
fullLine;
);
getExtraContent = Function({allLines}, {default local},
lines = Words(allLines, "\!n");
lastValue = N Items(lines);
startValue = Contains(allLines, lines[lastValue]);
last7 = Substr(allLines, -1);
if (last7 == "\!n",
extra = "",
extra = Substr(allLines, startValue);
);
extra;
);
Re: Read 기능으로 대량의 Run Program을 처리하는 방법다음과 같이 시도하십시오(외부 데이터 소스를 시뮬레이션하기 위해 Windows .bat 파일용으로 작성됨).
dt = New Table( "fetched", New Column( "a" ), New Column( "b" ), New Column( "c" ), New Column( "d" ), New Column( "bufsize" ) );
// https://stackoverflow.com/questions/2591758/batch-script-loop
bat = Save Text File( "$temp/data.bat", "@echo off\!nfor /l %%x in (1, 1, 100000) do echo %%x, 444, 555, 666" );
buffer = "";
runprog = RunProgram(
executable( "CMD.EXE" ),
options( {"/C", bat} ),
readfunction(
Function( {this},
{data},
While( this << canread,
buffer = buffer || (this << read);
While( Pat Match( buffer, Pat Break( "\!n" ) >> data + "\!n", "" ),
dt << addrow( 1 );
{dt:a, dt:b, dt:c, dt:d} = Words( data, "," );
dt:bufsize = Length( buffer );
If( Mod( N Rows( dt ), 1000 ) == 0,
Wait( 0 )
); // show the updates
);
)
)
)
);
100,000줄은 테이블 업데이트에 약간의 시간이 걸립니다(15초 정도). 다음과 같이 훨씬 빠르게(~4초) 실행됩니다.
dt = New Table( "fetched", New Column( "a" ), New Column( "b" ), New Column( "c" ), New Column( "d" ), New Column( "bufsize" ) );
// https://stackoverflow.com/questions/2591758/batch-script-loop
bat = Save Text File( "$temp/data.bat", "@echo off\!nfor /l %%x in (1, 1, 100000) do echo %%x, 444, 555, 666" );
buffer = "";
dt << begin Data Update;
runprog = RunProgram(
executable( "CMD.EXE" ),
options( {"/C", bat} ),
readfunction(
Function( {this},
{data},
While( this << canread,
buffer = buffer || (this << read);
While( Pat Match( buffer, Pat Break( "\!n" ) >> data + "\!n", "" ),
dt << addrow( 1 );
{dt:a, dt:b, dt:c, dt:d} = Words( data, "," );
dt:bufsize = Length( buffer );
);
)
)
)
);
Write( "\!nWaiting\!n" );
While( !(runprog << isreadeof), Wait( .01 ) );
dt << end Data Update;
Write( "\!nDone" );
<<데이터 업데이트 시작은 테이블이 많은 숫자의 서식을 지정하지 못하도록 합니다. 마지막에 있는 while은 데이터 업데이트를 다시 켜기 전에 실행 프로그램 개체가 읽기를 마칠 때까지 기다립니다. CMD.EXE 창은 .bat 파일의 출력을 스크롤하는 데 ~4초가 걸립니다.