2013-05-13 3 views
4

У меня есть файл .txt, который имеет 3 строки следующим образом:понимание потока и внутреннего буфера?

A50

B25

C25

Это мой код:

FileStream fs = new FileStream(@"E:\1.txt", FileMode.Open); 
StreamReader sr = new StreamReader(fs); 
textBox1.AppendText(sr.ReadLine() + "\r\n"); 
textBox1.AppendText(fs.Position.ToString()); 

Теперь после запуска выше кода, выход будет:

A50

Мой вопрос, почему значение позиции 14? почему это не 4, поскольку указатель потока указывает на символ «\ n», который находится в конце первой строки A50? Связано это с внутренним буфером? и что является внутренним буфером в деталях и как оно работает с streamreader?

извините за плохой английский.

+0

Обратите внимание, что даже если 'StreamReader' не читал никаких дополнительных данных, позиция файла по-прежнему была бы не менее 8, потому что каждый символ занимает два байта, а не один. Вы уверены, что хотите байты, а не символы? (Chars принимает 2 байта - по умолчанию - если вы не используете текст ASCII или ANSI.) –

+0

@MatthewWatson: Chars * может * принимать более одного байта каждый. Вы упомянули ASCII и ANSI. Несмотря на отсутствие кодировки ANSI, существует * много * 8-битных кодировок. И один символ в UTF-8 может иметь длину от 1 до 7 байтов. Высказывание «каждый символ занимает два байта» является правильным только при относительно небольшом числе кодировок. –

+0

@JimMischel Тем не менее, если вы посмотрите на фактический код, который опубликован OP, вы увидите, что он использует кодировку по умолчанию, поэтому он определенно будет не менее 2 байтов на символ. То, что я делал, это то, что это (по крайней мере) 2 байта на символ для кодировки * по умолчанию *, и это важно. –

ответ

3

Вопрос: почему значение позиции равно 14?

StreamReader имеет «переработку», чтобы выполнить относительно небольшое количество операций чтения в базовом потоке. Да, это связано с внутренним буфером - идея состоит в том, что он будет выполнять «короткие» операции чтения в базовом потоке, часто считывая больше, чем нужно, чтобы удовлетворить текущую операцию, тем самым предотвращая много однобайтовые чтения ,

Чтобы прочитать строку за раз, не подвергая чрезмерному чтению, нужно было бы прочитать только один байт , который может быть даже не одним символом. В зависимости от реализации потока это может быть неэффективным. Вместо этого он считывает в буфер, который является скрытой деталью реализации (у вас нет прямого доступа к буфере), а затем удовлетворяет запросы из этого буфера, пока он не будет снова читать из потока.

+0

Есть ли способ, чтобы я мог читать файл в однобайтовом порядке? – AWT

+2

@AbdulwadoudTah Для этого вам не нужен StreamReader; вы можете просто использовать '' FileStream.ReadByte() '] (http://msdn.microsoft.com/en-us/library/system.io.filestream.readbyte.aspx). Вы уверены, что вам не нужно читать символы а не байты? –

+1

@AbdulwadoudTah: Почему вы хотите? Какая здесь большая картина? –

3

StreamReader считывает данные с диска во внутренний буфер и затем удовлетворяет запросам этого буфера.

Он работает таким образом, чтобы уменьшить количество раз, когда он должен вызывать операционную систему для данных. Если он не имеет внутренний буфер, то он должен был бы сделать это:

while (not end-of-file and character != newline) 
{ 
    read next character and append to string 
} 

С внутреннего буфера, он читает большую порцию данных (по умолчанию это что-то вроде 4 Кбайта, но может быть изменен) в память. Затем он может быстро сканировать этот блок данных для символа новой строки и вернуть строку.

+0

Это было полезно, спасибо. – AWT

Смежные вопросы