Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.08.2009, 15:24   #11
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Попробовал всё то же самое в C#, при вызове StreamReader.Read (buffer, index, count) идут глюки:
1) требуется как минимум буфер char[count+9]
2) FileStream.Position увеличивается сразу на 1024
3) в буфере почти все символы оказываются нулевые (один-два оказываются случайными)

P. S.
Код:
FileStream FStream = new FileStream (FileName, FileMode.Open, FileAccess.Read);
StreamReader FTextReader = new StreamReader (FStream, Encoding.GetEncoding(866));
...
char[] buff = new char[20];
FTextReader.Read (buff, (int)FStream.Position, 11);
string str = new string (buff);

Последний раз редактировалось ds.Dante; 24.08.2009 в 17:16.
ds.Dante вне форума Ответить с цитированием
Старый 24.08.2009, 18:12   #12
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Всё, я разобрался:

Код:
char[] buff = new char[11];
FTextReader.Read (buff, 0, 11); // Второй аргумент - на самом деле смещение относительно FileStream.Position, поэтому раньше в начале были нули
string qwe = new string (buff);
qwe = qwe.TrimEnd ((char)0); // Удалаем все нули в конце
ds.Dante вне форума Ответить с цитированием
Старый 25.08.2009, 14:50   #13
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

Отлично, хоть сам буду знать этот момент. Тебе + в репутацию.
Hollander вне форума Ответить с цитированием
Старый 25.08.2009, 17:58   #14
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Блин, да там глюков - как маркетологов в MS. :D
1) после StreamReader.Read() величина FileStream.Position увеличивается на 1024
2) после того, как я компенсирую эту величину (FStream.Position += 11-1024), чтение продолжается не совсем оттуда, откуда нужно. Дело может быть во взаимодействии StreamReader и BinaryReader, который тоже используется с тем же файлом.
3) Я выполняю тот код в цикле, и после каждой итерации нужно очищать буфер. Я сделал объявление буфера внутри цикла, но его значение сохраняется. (Это, конечно, вопрос по основам C#).
ds.Dante вне форума Ответить с цитированием
Старый 26.08.2009, 17:49   #15
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

Цитата:
Сообщение от ds.Dante Посмотреть сообщение
Блин, да там глюков - как маркетологов в MS. :D
Я практически уверен, что там нету глюков, просто ты неправильно используешь.
Цитата:
Сообщение от ds.Dante Посмотреть сообщение
3) Я выполняю тот код в цикле, и после каждой итерации нужно очищать буфер. Я сделал объявление буфера внутри цикла, но его значение сохраняется. (Это, конечно, вопрос по основам C#).
Такого быть не может, только если ты не используешь статические переменные. Если их нет, значит твой код неверный.

Я помнб как-то читал побайтово файл и делал это через BinaryReader - проблем не было.
Hollander вне форума Ответить с цитированием
Старый 27.08.2009, 14:59   #16
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Цитата:
Сообщение от Hollander Посмотреть сообщение
Я практически уверен, что там нету глюков, просто ты неправильно используешь.
Я имел в виду свою программу. :)
Цитата:
Сообщение от Hollander Посмотреть сообщение
Такого быть не может, только если ты не используешь статические переменные. Если их нет, значит твой код неверный.
Точно, это я что-то напутал.
Цитата:
Сообщение от Hollander Посмотреть сообщение
Я помнб как-то читал побайтово файл и делал это через BinaryReader - проблем не было.
Мне кажется, дело именно во взаимодействии BinaryReader и StreamReader, поскольку у меня получается заставить работать только или один, или другой.
ds.Dante вне форума Ответить с цитированием
Старый 27.08.2009, 15:43   #17
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Вот код, наглядно демонстрирующий эту ошибку (Console Application):
Код:
using System;
using System.IO;

namespace ConsoleApplication1
{
	class Program
	{
		static void Main (string[] args)
		{
			try
			{
				FileStream FStream = new FileStream ("input.txt", FileMode.Open, FileAccess.Read);
				BinaryReader FBinReader = new BinaryReader (FStream);
				StreamReader FTextReader = new StreamReader (FStream);
				byte n;
				char[] buff = new char[3];

				for (int i = 0; i < 3; i++)
				{
					Console.WriteLine ("New iteration");
					Console.WriteLine (FStream.Position); // Каждый раз проверяем FStream.Position
					Console.WriteLine ();

					n = FBinReader.ReadByte ();
					Console.WriteLine ("n: {0}", n);
					Console.WriteLine (FStream.Position);
					Console.WriteLine ();

					FTextReader.Read (buff, 0, 3);
					Console.WriteLine ("buff: {0}", (new string (buff)).TrimEnd ((char)0));
					Console.WriteLine (FStream.Position);
					Console.WriteLine ();
				}

				FTextReader.Close ();
				FBinReader.Close ();
				FStream.Close ();
			}
			catch (Exception exc)
			{
				Console.WriteLine (exc.Message);
			}

			Console.ReadKey ();
		}
	}
}
Файл input.txt:
Код:
ABCDEFGHIJKL
Должен вывести:
Цитата:
New iteration
0

n: 65
1

buff: BCD
4

New iteration
4

n: 69
5

buff: FGH
8

New iteration
8

n: 73
9

buff: BCE
12
Выводит:
Цитата:
New iteration
0

n: 65
1

buff: BCD
12

New iteration
12

Unable to read beyond the end of the stream.
Т. е. StreamReader.Read() "портит" переменную FileStream.Position, устанавливая ее всегда 12 (т. е. размер файла, но не больше 1024), но сам при этом может нормально дальше читать файл (это видно если закомментировать чтение через BinaryReader).

P. S. если есть какие-то "придирки" по стилю C# - буду рад выслушать. :)

Последний раз редактировалось ds.Dante; 27.08.2009 в 15:46.
ds.Dante вне форума Ответить с цитированием
Старый 27.08.2009, 18:00   #18
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Всё, похоже я разобрался.

Во-первых, в StreamReader.Read() аргумент index просто добавляется к count, т. е. из файла читается и записывается в буфер index+count байт.

Во-вторых, проблемы с взаимодействием StreamReader и BinaryReader можно обойти, если разными способами устанавливать их позиции чтения. В коде это выглядит так:
Код:
using System;
using System.IO;

namespace ConsoleApplication1
{
	class Program
	{
		static void Main (string[] args)
		{
			try
			{
				FileStream FStream = new FileStream ("input.txt", FileMode.Open, FileAccess.Read);
				BinaryReader FBinReader = new BinaryReader (FStream);
				StreamReader FTextReader = new StreamReader (FStream);
				byte n;
				char[] buff = new char[3];

				for (int i = 0; i < 3; i++)
				{
					Console.WriteLine ("New iteration");
					Console.WriteLine (FStream.Position);
					Console.WriteLine ();

					FStream.Position = i * 4; // Здесь заново устанавливаем BinaryReader
					n = FBinReader.ReadByte ();
					Console.WriteLine ("n: {0}", n);
					Console.WriteLine (FStream.Position);
					Console.WriteLine ();

					FStream.Position = 0; // Зачем-то обнуляем... :)
					FTextReader.Read (buff, 0, 1); // ...и пропускаем количество байт, которые прочитали с помощью BinaryReader
					FTextReader.Read (buff, 0, 3);
					Console.WriteLine ("buff: {0}", (new string (buff)).TrimEnd ((char)0));
					Console.WriteLine (FStream.Position);
					Console.WriteLine ();
				}

				FTextReader.Close ();
				FBinReader.Close ();
				FStream.Close ();
			}
			catch (Exception exc)
			{
				Console.WriteLine (exc.Message);
			}

			Console.ReadKey ();
		}
	}
}
У меня остается только один вопрос - неужели создатели .NET действительно сделали чтение из файла через такую задницу, или то же самое можно как-то сделать проще?

Последний раз редактировалось ds.Dante; 27.08.2009 в 18:03.
ds.Dante вне форума Ответить с цитированием
Старый 28.08.2009, 11:51   #19
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

В продолжение темы: можно ли как-нибудь одной функцией обнулить char[]? Или только присваивать нули в цикле?
ds.Dante вне форума Ответить с цитированием
Старый 31.08.2009, 17:26   #20
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Не поверите, но у меня опять ошибка. :) После 25-го цикла чтение начинается с начала файла. К сожалению, я не могу показать это в сколько-нибудь удобочитаемом виде, поэтому мне остается только переписать чтение на C++. :)
Даже если я что-то делаю не так - меня удивляет, что нигде нет информации по этой теме (совместное использование StreamReader и BinaryReader).
ds.Dante вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как прочитать из файла имя, фамилию разделенные пробелами и записать их в массив парами Rom@shka Общие вопросы C/C++ 2 13.12.2008 16:40
Как из юникодного текстового файла прочитать его построчно и неповторяющиеся слова ввести в ListBox? SkAndrew Общие вопросы Delphi 2 10.11.2008 22:14
Прочитать строку до конца Иллидан Общие вопросы C/C++ 3 28.09.2008 02:21
Не получается прочитать из файла...( Regloger Помощь студентам 3 09.12.2007 14:23
Как мне в асме прочитать данные из файла? lelicman Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 10.10.2007 09:24