Специальные символы в StreamWriter - PullRequest
1 голос
/ 07 марта 2012

Я использую streamwriter для записи строки в поток.Теперь, когда я получаю доступ к данным из потока, он добавляет символы «\ 0 \ 0 \ 0» в конец содержимого.Я должен добавить содержимое потока, поэтому это создает проблему, так как я не могу удалить эти символы методами trim () или remove () или replace ().

Ниже приведен код, который я использую:

ДЛЯ ПИСАНИЯ:

using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
    using (StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Unicode))
    {
        try
        {
            string[] files = System.IO.Directory.GetFiles(folderName, "*.*", System.IO.SearchOption.AllDirectories);
            foreach (string str in files)
            {
                writer.WriteLine(str);
            }
            // writer.WriteLine(folderName);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Unable to write string. " + ex);
        }
        finally
        {
            mutex.ReleaseMutex();
            mutex.WaitOne();
        }
    }
}

ДЛЯ ЧТЕНИЯ:

 StringBuilder sb = new StringBuilder();
            string str = @"D:\Other Files\Test_Folder\New Text Document.txt";
 using (var stream = mmf.CreateViewStream())
                {
                    System.IO.StreamReader reader = new System.IO.StreamReader(stream);
                    sb.Append(reader.ReadToEnd());
                    sb.ToString().Trim('\0');
                    sb.Append("\n" + str);
                }

Как я могу предотвратить это?

[ОБНОВЛЕНИЯ] Письмо

// Lock
            bool mutexCreated;
            Mutex mutex = new Mutex(true, fileName, out mutexCreated);
            if (!mutexCreated)
                mutex = new Mutex(true);
            try
            {
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        try
                        {
                            string[] files = System.IO.Directory.GetFiles(folderName, "*.*", System.IO.SearchOption.AllDirectories);
                            foreach (string str in files)
                            {
                                writer.Write(str);
                            }
                            writer.Flush();
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine("Unable to write string. " + ex);
                        }
                        finally
                        {
                            mutex.ReleaseMutex();
                            mutex.WaitOne();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Unable to monitor memory file. " + ex);
            }

Чтение

StringBuilder sb = new StringBuilder();
            string str = @"D:\Other Files\Test_Folder\New Text Document.txt";
            try
            {
                using (var stream = mmf.CreateViewStream())
                {
                    System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);
                    sb.Append(reader.ReadString());
                    sb.Append("\n" + str);
                }
                using (var stream = mmf.CreateViewStream())
                {
                    System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream);
                    writer.Write(sb.ToString());
                }
                using (var stream = mmf.CreateViewStream())
                {
                    System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);
                    Console.WriteLine(reader.ReadString());
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Unable to monitor memory file. " + ex);
            }

Ответы [ 2 ]

4 голосов
/ 07 марта 2012

No '\ 0' не добавляется StreamWriter.Это просто содержимое отображенного в память файла, вещи, которые были там до , когда вы начали писать.StreamReader нужен индикатор конца файла, чтобы знать, когда прекратить чтение.В ММФ нет ничего, кроме размера раздела.Как и второй аргумент, который вы передаете MemoryMappedFile.CreateNew (string, long).

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

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

Я не вижу хорошего способа научить StreamReader новым приемам в этом случае.Копирование байтов из MMF в MemoryStream решило бы проблему, но скорее победило бы точку MMF.

Попробуйте вместо этого использовать трубу.

2 голосов
/ 07 марта 2012

Ваша комбинация MMF и TextWriter / TextReader, особенно ReadToEnd (), не очень подходит.

Для textReader нужна концепция EOF базового файла, а MMF просто не предоставляет это таким же образом. Вы наберете свои струны \0\0... до емкости MMF.

Как возможное исправление:

  • собрать строки для записи в StringBuilder
  • используйте BinaryWriter, чтобы записать его как 1 строку
  • читать его обратно с помощью BinaryReader.

Другим вариантом является использование WriteLine / ReadLine и определение некоторого маркера EOF (пустая строка или специальная строка).

BinaryWriter будет префикс строки с префиксом длины, чтобы Читатель знал, когда остановиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...