텍스트 파일 내에서 줄 수를 프로그래밍 방식으로 쉽게 결정할 수 있습니까?
답변
심각하게 뒤늦은 편집 : .NET 4.0 이상을 사용하는 경우
이 File
클래스에는 ReadLines
행을 모두 탐욕스럽게 읽지 않고 게으르게 열거 하는 새로운 메소드가 ReadAllLines
있습니다. 이제 효율성과 간결성을 모두 얻을 수 있습니다.
var lineCount = File.ReadLines(@"C:\file.txt").Count();
원래 답변
효율성에 대해 너무 신경 쓰지 않으면 간단히 다음과 같이 쓸 수 있습니다.
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
보다 효율적인 방법을 위해 다음을 수행 할 수 있습니다.
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
편집 : 효율성에 대한 질문에 대한 답변
두 번째가 더 효율적이라고 말한 이유는 반드시 속도가 아니라 메모리 사용에 관한 것이 었습니다. 첫 번째 파일은 파일의 전체 내용을 배열로로드합니다. 즉, 파일의 크기만큼 메모리를 할당해야합니다. 두 번째는 한 번에 한 줄씩 반복하므로 한 번에 두 줄 이상의 메모리를 할당 할 필요가 없습니다. 작은 파일의 경우 그렇게 중요하지 않지만 큰 파일의 경우 문제가 될 수 있습니다 (예를 들어 32 비트 시스템에서 4GB 파일의 줄 수를 찾으려면 충분하지 않습니다) 이 큰 배열을 할당하기위한 사용자 모드 주소 공간).
속도면에서 나는 그것에 많이있을 것으로 기대하지 않을 것입니다. ReadAllLines에 내부 최적화가있을 수 있지만 다른 한편으로는 엄청난 양의 메모리를 할당해야 할 수도 있습니다. 작은 파일의 경우 ReadAllLines가 더 빠를 수 있지만 큰 파일의 경우 크게 느려질 수 있습니다. 말할 수있는 유일한 방법은 스톱워치 또는 코드 프로파일 러로 측정하는 것입니다.
답변
제일 쉬운:
int lines = File.ReadAllLines("myfile").Length;
답변
메모리를 적게 사용하지만 시간이 더 오래 걸립니다
int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
count++;
}
reader.Close();
답변
쉽게 해독 할 수 있지만 기회 당 비효율적 인 코드 줄을 의미합니까?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
그것은 아마도 몇 줄을 알 수있는 가장 빠른 방법 일 것입니다.
당신은 또한 할 수 있습니다 (버퍼링하는지에 따라)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
다른 많은 방법이 있지만 위의 방법 중 하나가 아마도 당신과 함께 갈 것입니다.
답변
텍스트를 전혀 읽지 않고 빠르게 읽고 카운터를 증가시킬 수 있습니다. 루프를 사용하여 증가시킬 수 있습니다.
답변
파일을 읽고 그 자체로 시간이 오래 걸리고, 결과를 가비지 수집하는 것은 개행 문자를 세기 위해 전체 파일을 읽을 때 또 다른 문제입니다.
어느 시점에서 누군가 프레임 워크 또는 코드인지 여부에 관계없이 파일의 문자를 읽어야합니다. 이것은 파일이 크면 파일을 열고 메모리로 읽어야한다는 것을 의미합니다. 메모리가 가비지 수집되어야하기 때문에 잠재적으로 문제가 될 수 있습니다.
Nima Ara는 당신이 고려할만한 훌륭한 분석을했습니다.
다음은 한 번에 4자를 읽고 줄 바꿈 문자를 세고 다음 문자 비교를 위해 동일한 메모리 주소를 다시 재사용함에 따라 제안 된 솔루션입니다.
private const char CR = '\r';
private const char LF = '\n';
private const char NULL = (char)0;
public static long CountLinesMaybe(Stream stream)
{
Ensure.NotNull(stream, nameof(stream));
var lineCount = 0L;
var byteBuffer = new byte[1024 * 1024];
const int BytesAtTheTime = 4;
var detectedEOL = NULL;
var currentChar = NULL;
int bytesRead;
while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
var i = 0;
for (; i <= bytesRead - BytesAtTheTime; i += BytesAtTheTime)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 1];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 2];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 3];
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
i -= BytesAtTheTime - 1;
}
}
for (; i < bytesRead; i++)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
}
}
}
if (currentChar != LF && currentChar != CR && currentChar != NULL)
{
lineCount++;
}
return lineCount;
}
위에서 당신은 줄 바꿈을보기 위해 모든 문자를 읽을 필요가있을 때 기본 프레임 워크에 의해 한 번에 한 문자 씩 읽히는 것을 볼 수 있습니다.
완료된 베이 니마로 프로파일 링하면 이것이 빠르고 효율적인 방법임을 알 수 있습니다.
답변
캐리지 리턴 / 라인 피드를 계산합니다. 나는 유니 코드를 믿는데 여전히 각각 0x000D와 0x000A입니다. 그렇게하면 원하는만큼 효율적이거나 비효율적 일 수 있고 두 캐릭터를 다룰 것인지 아닌지를 결정할 수 있습니다