.NET C# - Произвольный доступ в текстовых файлах - никакой простой способ?

Давайте предположим, что ваши входные данные - это словарь. Затем вы можете использовать NumPy для векторизованного решения. Сначала вы преобразуете свои входные списки в массив NumPy и используете аргумент axis=1, чтобы получить RMSE.

# Input data
dicts = {0: [0, 0, 0, 0], 1: [1, 0, 0, 0], 2: [1, 1, 0, 0], 3: [1, 1, 1, 0],4: [1, 1, 1, 1]}
new_value = np.array([0.9539342, 0.84090066, 0.46451256, 0.09715253])

# Convert values to array
values = np.array(list(dicts.values()))

# Compute the RMSE and get the index for the least RMSE 
rmse = np.mean((values-new_value)**2, axis=1)**0.5
index = np.argmin(rmse)    

print ("The closest value is %s" %(values[index]))
# The closest value is [1 1 0 0]
21
задан chills42 5 November 2008 в 06:16
поделиться

9 ответов

Я думаю, что функция записей времени выполнения библиотеки FileHelpers могла бы помочь u. http://filehelpers.sourceforge.net/runtime_classes.html

1
ответ дан 17 October 2019 в 01:14
поделиться

Вы уверены, что файл является "слишком большим"? Вы попробовали его тот путь, и это вызвало проблему?

при выделении большого объема памяти, и Вы не используете его прямо сейчас, Windows просто выгрузит его к диску. Следовательно, путем доступа к нему от "памяти", Вы выполните то, что Вы хотите - произвольный доступ к файлу на диске.

0
ответ дан 17 October 2019 в 01:14
поделиться

Этот точный вопрос задали в 2006 здесь: http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic40275.aspx

Сводка:

"Проблема состоит в том, что StreamReader буферизует данные, таким образом, значение, возвращенное в BaseStream. Свойство Position всегда перед фактической обработанной строкой".

Однако, "если файл кодируется в текстовом кодировании, которое является фиксированной шириной, Вы могли отслеживать то, сколько текста было прочитано и умножает это на ширину"

, и в противном случае можно просто использовать FileStream и считать символ за один раз и затем BaseStream. Свойство Position должно быть корректно

0
ответ дан 17 October 2019 в 01:14
поделиться

Пара элементов, которые могут вас заинтересовать.

1) Если строки представляют собой фиксированный набор символов по длине, это не обязательно полезная информация, если набор символов имеет переменные размеры (например, UTF-8). Так что проверьте свой набор символов.

2) Вы можете определить точное положение файлового курсора из StreamReader, используя значение BaseStream.Position IF , вы сначала очистите () буферы (что приведет к тому, что текущая позиция будет там, где следующая чтение начнется - через один байт после последнего прочитанного байта).

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

4) Есть ли какая-то конкретная причина, по которой, если строки имеют одинаковую длину (предполагая здесь в байтах), вы не просто используете номера строк и не вычисляете байтовое смещение в файле на основе размера строки x номера строки ?

1
ответ дан 17 October 2019 в 01:14
поделиться

Можно использовать Систему. IO.FileStream вместо StreamReader. Если Вы знаете точно, что содержит файл (кодирование, например), можно сделать всю операцию как с StreamReader.

5
ответ дан 17 October 2019 в 01:14
поделиться

FileStream имеет искание () метод.

7
ответ дан 17 October 2019 в 01:14
поделиться

Действительно ли кодирование является фиксированным размером один (например, ASCII или UCS-2)? Если так, Вы могли отслеживать индекс символа (на основе количества символов, которые Вы видели), и найдите двоичный индекс на основе этого.

Иначе, нет - необходимо было бы в основном записать собственную реализацию StreamReader, которая позволяет Вам посмотреть на двоичный индекс. Это - позор, что StreamReader не реализует это, я соглашаюсь.

2
ответ дан 17 October 2019 в 01:14
поделиться

Если Вы гибки с тем, как файл данных записан, и не возражайте против него являющийся немного менее благоприятным для текстового редактора, Вы могли записать свои записи с BinaryWriter:

using (BinaryWriter writer = 
    new BinaryWriter(File.Open("data.txt", FileMode.Create)))
{
    writer.Write("one,1,1,1,1");
    writer.Write("two,2,2,2,2");
    writer.Write("three,3,3,3,3");
}

Затем первоначально чтение каждой записи просто, потому что можно использовать метод ReadString BinaryReader:

using (BinaryReader reader = new BinaryReader(File.OpenRead("data.txt")))
{
    string line = null;
    long position = reader.BaseStream.Position;
    while (reader.PeekChar() > -1)
    {
        line = reader.ReadString();

        //parse the name out of the line here...

        Console.WriteLine("{0},{1}", position, line);
        position = reader.BaseStream.Position;
    }
}

BinaryReader не буферизуется так, Вы заставляете надлежащее положение хранить и использовать позже. Единственная стычка анализирует имя из строки, которая можно иметь отношение к StreamReader так или иначе.

5
ответ дан 17 October 2019 в 01:14
поделиться

There are some good answers provided, but I couldn't find some source code that would work in my very simplistic case. Here it is, with the hope that it'll save someone else the hour that I spent searching around.

The "very simplistic case" that I refer to is: the text encoding is fixed-width, and the line ending characters are the same throughout the file. This code works well in my case (where I'm parsing a log file, and I sometime have to seek ahead in the file, and then come back. I implemented just enough to do what I needed to do (ex: only one constructor, and only override ReadLine()), so most likely you'll need to add code... but I think it's a reasonable starting point.

public class PositionableStreamReader : StreamReader
{
    public PositionableStreamReader(string path)
        :base(path)
        {}

    private int myLineEndingCharacterLength = Environment.NewLine.Length;
    public int LineEndingCharacterLength
    {
        get { return myLineEndingCharacterLength; }
        set { myLineEndingCharacterLength = value; }
    }

    public override string ReadLine()
    {
        string line = base.ReadLine();
        if (null != line)
            myStreamPosition += line.Length + myLineEndingCharacterLength;
        return line;
    }

    private long myStreamPosition = 0;
    public long Position
    {
        get { return myStreamPosition; }
        set
        {
            myStreamPosition = value;
            this.BaseStream.Position = value;
            this.DiscardBufferedData();
        }
    }
}

Here's an example of how to use the PositionableStreamReader:

PositionableStreamReader sr = new PositionableStreamReader("somepath.txt");

// read some lines
while (something)
    sr.ReadLine();

// bookmark the current position
long streamPosition = sr.Position;

// read some lines
while (something)
    sr.ReadLine();

// go back to the bookmarked position
sr.Position = streamPosition;

// read some lines
while (something)
    sr.ReadLine();
13
ответ дан 17 October 2019 в 01:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: