(대형 파일에 사용 가능) 텍스트 파일을 빠르게 스캔하여 행 수를 집계하고 각 행의 인덱스 위치(Delphi, C#)를 반환합니다.
5436 단어 C#학습 노트
다음은 Delphi 코드입니다.
//
function ScanEnterFile(const FileName:string):TInt64Array;
var
MyFile:TMemoryStream;//
rArray:TInt64Array; //
size,curIndex:int64;// ,
enterCount:int64;//
DoLoop:Boolean;//
pc: PChar;
arrayCount:int64;//
addStep:integer;//
begin
if fileName = '' then
Exit;
if not FileExists(fileName) then
Exit;
MyFile:=TMemoryStream.Create;//
MyFile.LoadFromFile(fileName);// MyFile
size:=MyFile.Size;
pc:=MyFile.Memory; //
curIndex:=RowLeast;
DoLoop:=true;
enterCount:=0;
setlength(rArray,perArray);
arrayCount:=perArray;
enterCount:=0;
rArray[enterCount]:=0;
while DoLoop do
begin
addStep:=0;
if (ord(pc[curIndex])=13) then
addStep:=2;
if (ord(pc[curIndex])=10) then
addStep:=1;
//
if (addStep<>0) then
begin
Application.ProcessMessages;
//
inc(enterCount);
//
if (enterCount mod perArray=0) then
begin
arrayCount:=arrayCount+perArray;
setlength(rArray,arrayCount);
end;
rArray[enterCount]:=curIndex+addStep;
curIndex:=curIndex+addStep+RowLeast;
end
else
curIndex:=curIndex+2;
if curIndex> size then
DoLoop:=false
else
DoLoop:=true;
end;
result:=rArray;
freeandnil(MyFile);
end;
실행 코드:
procedure TMainForm.btn2Click(Sender: TObject);
var
datasIndex:TInt64Array;//
begin
t1:=GetTickCount;
datasIndex:=ScanEnterFile('R:\201201_dataFile.txt');
Caption:=Caption+'::'+inttostr(GetTickCount-t1);
end;
실행 결과: 16782ms
다음은 C# 코드입니다.
///
/// , , (1.2KW 10 )
///
///
///
///
///
///
///
public static IList ScanEnterFile(string fileName, out int rowCount, int rowLeast,ThreadProgress progress)
{
rowCount = 0;
if (string.IsNullOrEmpty(fileName))
return null;
if (!System.IO.File.Exists(fileName))
return null;
FileStream myFile = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8);//
IList rList=new List();
int enterCount = 0;//
int checkValue;
int addStep;
myFile.Position = rowLeast;
checkValue = myFile.ReadByte();
while (checkValue != -1)
{
//Application.DoEvents();
addStep = -1;
// ReadByte , 。
// , , 。
// ,
if (checkValue == 13)
addStep = 1;
else if (checkValue == 10)
addStep = 0;
if (addStep >= 0)
{
enterCount++;
rList.Add(myFile.Position + addStep);
myFile.Seek(rowLeast + addStep, SeekOrigin.Current);
progress(enterCount);
}
else myFile.Seek(2, SeekOrigin.Current);
checkValue = myFile.ReadByte();
}
rowCount = enterCount + 1;
return rList;
}
실행 코드:
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int rowCount;
FileHelper.ScanEnterFile(@"R:\201201_dataFile.txt", out rowCount, 35, outputProgress);
useTime = stopwatch.ElapsedMilliseconds;
실행 결과:
124925 ms
(많은 네티즌들의 비판과 지적을 통해 이 방법은 파일을 메모리에서 읽지 않고 한 바이트씩 읽는다. Delphi 바이트가 메모리에 들어가는 방법보다 속도가 훨씬 느리다. 이런 방법은 낡은 기계에만 적합하다. 메모리가 부족한 상황에서 현재 메모리는 이미 매우 싸다. 그래서 이 방법은 현재 이미 유행이 지났다. 다음은 네티즌의 지적을 거쳐readline 방법을 사용했다. 속도는 약 6초 정도이다.)
public static IList ScanEnterFile(string fileName, ThreadProgress progress)
{
if (string.IsNullOrEmpty(fileName))
return null;
if (!System.IO.File.Exists(fileName))
return null;
IList rList = new List();
rList.Add(0);
StreamReader sr = File.OpenText(fileName);
string rStr = sr.ReadLine();
while (null != rStr)
{
rList.Add(rList[rList.Count-1] + rStr.Length + 2);
rStr = sr.ReadLine();
progress(rList.Count);
}
sr.Close();
return rList;
}
테스트를 통해 이 방법은 중국어 문자 인코딩이 존재할 때 위치가 잘못되었습니다.나중에 해결 방법을 찾은 후에 다시 올라와서 갱신하세요.
테스트 결과 C# 은 배열보다 Ilist 를 더 빨리 사용합니다.
총괄: 모든 사물은 존재할 가치가 있다. 관청에서 무엇을 선택하는지는 자신의 수요에 따라 선택한다. 여기서 본인은 어느 쪽에 치우치지 않는다.어쨌든 일을 이룰 수 있다면 아무것도 중요하지 않다.
오리지널 작품은 열심히 게으름을 피우는 데서 나온 것이니, 옮겨 싣고 설명해 주십시오.
글의 출처
: http://blog.csdn.net/kfarvid
또는
http://www.cnblogs.com/kfarvid/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
(대형 파일에 사용 가능) 텍스트 파일을 빠르게 스캔하여 행 수를 집계하고 각 행의 인덱스 위치(Delphi, C#)를 반환합니다.프로젝트에 따라 1200만 줄의 텍스트 파일을 스캔해야 합니다.네티즌의 지적과 테스트를 통해 C#와 델피의 차이가 결코 크지 않다는 것을 발견하였다.긴 설명 없이 열 코드 테스트: 다음은 Delphi 코드입니다. 실...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.