GZipStream, как правильно читать из GZipStream - PullRequest
0 голосов
/ 06 февраля 2010

У меня есть код, написанный мной на C #

        string host = new Uri(_url).Host;
        IPHostEntry ipAddress = Dns.GetHostEntry(host);
        IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
        using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
        {
            s.Connect(ip);
            using (NetworkStream n = new NetworkStream(s))
            {
                    byte[] write = encoding.GetBytes(HttpQuery);
                    n.Write(write, 0, write.Length);
                    ReadLine(n);
                    Dictionary<string, string> headers = new Dictionary<string, string>();
                    while (true)
                    {
                        string line = ReadLine(n);
                        if (line.Length == 0)
                        {
                            break;
                        }
                        int index = line.IndexOf(':');
                        if (!headers.ContainsKey(line.Substring(0, index)))
                        {
                            headers.Add(line.Substring(0, index), line.Substring(index + 2));
                        }
                    }

                    string contentEncoding;
                    if (headers.TryGetValue("Content-Encoding", out contentEncoding))
                    {
                        Stream responseStream = n;
                        if (contentEncoding.Equals("gzip"))
                        {
                            responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                            responseStream.Flush();
                        }
                        else if (contentEncoding.Equals("deflate"))
                        {
                            responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        }

                        MemoryStream memStream = new MemoryStream();

                        byte[] respBuffer = new byte[4096];
                        try
                        {
                            int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            //int bytesRead = responseStream.ReadByte();
                            while (bytesRead > 0)
                            {
                                memStream.Write(respBuffer, 0, bytesRead);
                                bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            }
                        }
                        finally
                        {
                            responseStream.Close();
                        }
                        string str = encoding.GetString(memStream.ToArray());

Тогда у меня исключение InvalidDataException в этой строке int bytesRead = responseStream.Read (respBuffer, 0, respBuffer.Length);

Неправильный магический номер заголовка GZip.

    string ReadLine(Stream stream)
    {
        List<byte> lineBuffer = new List<byte>();
        try
        {
            while (true)
            {
                int b = stream.ReadByte();
                if (b == -1)
                    return null;
                if (b == 10)
                    break;
                if (b != 13)
                    lineBuffer.Add((byte) b);
            }
        }
        catch (Exception)
        {
        }
        return encoding.GetString(lineBuffer.ToArray());
    }

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2010

В общем, я нашел что-то по теме, вот Сокеты в C #: Как получить поток ответа? ссылка, есть некоторая информация, что перед строкой (-ами) сделать это:

                        Stream responseStream = n;
                        int magicNumber = 0;
                        while (magicNumber != 10)
                        {
                            magicNumber = responseStream.ReadByte();
                        }
                        if (contentEncoding.Equals("gzip"))
                        {
                            responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        }

возможно, я не совсем правильно сделал?

nobugz У меня очень успешный код, написанный с помощью WttWebRequest и HttpWebResponse, НО моя страница имеет codepape-1251, а HttpWebRequest конвертирует URL из кодировки 1251 в UTF-8. Я ничего не могу с этим поделать, может быть, у вас есть какие-нибудь идеи?

Например, у меня есть URL-адрес http://myurl.php? Name = Мастер% 20Создатель

HttpWebRequest преобразовать это в http://myurl.php? Name =% d0% 9c% d0% b0% d1% 81% d1% 82% d0% b5% d1% 80 + % d0% a1% d0% be% d0% b7% d0% b4% d0% b0% d1% 82% d0% b5% d0% bb% d1% 8c (UTF-8)

НО будет http://myurl.php? Name =% CC% E0% F1% F2% E5% F0% 20% D1% EE% E7% E4% E0% F2% E5% EB% FC (windows-1251), я не знаю, как это исправить

0 голосов
/ 06 февраля 2010

Ваша функция ReadLine возвращается, как только она читает один символ перевода строки при чтении пустой строки. Разве это не оставляет поток в позиции символа возврата каретки вместо начала потока данных GZip?

...