Итак, я хочу иметь возможность искать точку в файловом потоке, а затем читать вперед с помощью StreamReader. Затем снова выполните поиск вперед и используйте StreamReader для чтения другого фрагмента данных.
const int BufferSize = 4096;
var buffer = new char[BufferSize];
var endpoints = new List<long>();
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var fileLength = fileStream.Length;
var seekPositionCount = fileLength / concurrentReads;
long currentOffset = 0;
for (var i = 0; i < concurrentReads; i++)
{
var seekPosition = seekPositionCount + currentOffset;
// seek the file forward
fileStream.Seek(seekPosition, SeekOrigin.Current);
// setting true at the end is very important, keeps the underlying fileStream open.
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize, true))
{
// this also seeks the file forward the amount in the buffer...
int bytesRead;
var totalBytesRead = 0;
while ((bytesRead = await streamReader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
totalBytesRead += bytesRead;
var found = false;
var gotR = false;
for (var j = 0; j < buffer.Length; j++)
{
if (buffer[j] == '\r')
{
gotR = true;
continue;
}
if (buffer[j] == '\n' && gotR)
{
// so we add the total bytes read, minus the current buffer amount read, then add how far into the buffer we actually read.
seekPosition += totalBytesRead - BufferSize + j;
endpoints.Add(seekPosition);
found = true;
break;
}
}
if (found) break;
}
}
// we need to seek to the position we got to in the StreamReader (but not going by how much was read).
fileStream.Seek(seekPosition, SeekOrigin.Current);
currentOffset += seekPosition;
}
}
return endpoints;
Однако я добираюсь до двух записей в endpoints
, и он выходит.
(bytesRead = await streamReader.ReadAsync(buffer, 0, buffer.Length)) > 0
Я думал, что аргументы, которые вы передаете ReadAsync
, относятся исключительно к буферу, поэтому я думал, что аргумент index
должен был сказать: заполнить buffer
в index
.
Я не могу понять из справочного источника, как это используется значение.
Я предположил (и не могу найти доказательств для подтверждения), что когда вы открываете StreamReader
, он использует базовый Stream
в качестве руководства, поэтому, когда вы попросите прочитать несколько байтов, он начнется с позиции, в которой находится базовый Stream
. ...
Но результаты того, что я делаю, не показывают этого, они, кажется, показывают, что StreamReader
каждый раз начинается в начале Stream
- однако я не могу найти доказательства, подтверждающие, что это так. это либо...
Ищу
Верно ли мое понимание поиска в том смысле, что если я назову поиск
fileStream.Seek(seekPosition, SeekOrigin.Current);
Если файл находится в 300
, я хочу найти 600
, указанная выше переменная seekPosition
должна быть 600
??
ReferenceSource сказал бы иначе:
else if (origin == SeekOrigin.Current) {
// Don't call FlushRead here, which would have caused an infinite
// loop. Simply adjust the seek origin. This isn't necessary
// if we're seeking relative to the beginning or end of the stream.
offset -= (_readLen - _readPos);
}