DOBON.NET DOBON.NETプログラミング掲示板過去ログ

プロパティーのサイズより少なくなります。

環境/言語:[Windows XP]
分類:[.NET]

度々、投稿しまして大変申し訳ありません。
ご指導によりサイズを取得表示する事ができました。
TextBox1.Text = Len(srRead.ReadToEnd())
実際はプロパティーのサイズ(バイト)より少なくなります。
思うにはChr(&HDS)、 Chr(&HAS)は文字数に加算されない分
少なくなっていると思っています。もし、そうでありましたら、
何か良い方法はありますでしょうか。
ご存知の方がおりましたら宜しくお願いします。
lenは文字数です。

len("abc")は3
len("日本語環境")は5です。

そこの認識はあっていますか?
2006/02/22(Wed) 11:20:42 編集(投稿者)

中博俊 さん早々、返信頂きまして有り難うございました。
全角、半角も1になることもあることは知っていましたが、
今回は関係ないと思っていました。Chr(&HDS)、Chr(&HAS)
が関係していると思っていました。
全角、半角が関係している事が分かりました。
有り難うございました。
すみません。サイズを取得表示は
ご指導してもらいましたWebClient クラス
で取得しています。全角、半角の判別は
可能でしょうか。
2006/02/22(Wed) 11:11:55 編集(投稿者)

VB.NETのサンプル・プログラムに参考例が有りましたので調べて見ます。
HttpWebRequest クラスでヘッダーを調べることは出来ますが、
ヘッダー情報にはファイルサイズが見あたりませんでした。
有れば一番良いのですが。質問ですが、WebClient クラス
のヘッダー内容と、WebClient クラスの内容は違うのでしょうか。
違いがあれとすればWebClient クラスにはサイズ情報はあるのでしょうか。
ご存知の方がおりましたら、その点につきましてお聞き出来ませんでしょうか。
宜しくお願いします。
調べ方はなんとなく分かりました。
VB6ではLenBは使用できましたが
.NETからは宣言されていませんでした。
LenBに変わる何か参考になるものは
ありませんでしょうか。
> HttpWebRequest クラスでヘッダーを調べることは出来ますが、
> ヘッダー情報にはファイルサイズが見あたりませんでした。

Content-Length ヘッダが存在しなかったのですか?

Content-Length ヘッダは、HTTP リクエスト送信後に得られる情報ですが、ヘッダ取得までの手順に間違いは無いですか?

> 質問ですが、WebClient クラス
> のヘッダー内容と、WebClient クラスの内容は違うのでしょうか。

質問の意味が分かりません。

「WebClient クラスの内容」とは、何のことでしょう?
> ご指導によりサイズを取得表示する事ができました。

省略しないで、「どうやっているのか」手順をきちんと書いてください。
あなたが理解していることでも、他の人にはまったく分からないことの方が多いのです。

> TextBox1.Text = Len(srRead.ReadToEnd())
> 実際はプロパティーのサイズ(バイト)より少なくなります。

WebClient.OpenRead() しているものと仮定して回答します。

「コンテンツの長さを得る」ための手順が不適切と思われます。

サーバコンテンツの Encoding がはっきり分かっていて StreamReader を使っているのでしょうか?

サーバコンテンツの Encoding と、StreamReader の Encoding が食い違っていれば、コンテンツの長さは得られません。

ネットワーク系(かもしれない)Stream に対して Seek することもできないので、OpenRead() によって取得した Stream に対して小刻みに Read() を実行して、読み取った結果を MemoryStream に追記保存し、MemoryStream.ToArray() で作成された byte 配列の長さを検査するのが妥当な手順と思います。
■No15200に返信(ymoさんの記事)
> 調べ方はなんとなく分かりました。
> VB6ではLenBは使用できましたが
> .NETからは宣言されていませんでした。
> LenBに変わる何か参考になるものは
> ありませんでしょうか。

Google などの検索エンジンの「調べ方」もなんとなく分かってください。
「LenB + VB.NET」で検索すると、一発でヒットしませんか?

___________________________________________________________________________________
じゃんぬ - Microsoft MVP for Visual Developer C#
  C#, VB.NET 入門  http://jeanne.wankuma.com/
  じゃんぬねっと日誌 http://blogs.wankuma.com/jeanne/
渋木宏明(ひどり) さん返信ありがとうございました。
省略してしまいまして大変申し訳ありませんでした。
遅れましたが、そのまま記述しました。

Dim webClient As New System.Net.WebClient()

Dim sr As System.IO.Stream = webClient.OpenRead(text5.Text)

Dim srRead As New System.IO.StreamReader(sr)

TextBox3.Text = Len(srRead.ReadToEnd())
'TextBox3.Text = srRead.ReadToEnd() 'ソース表示

srRead.Close()

今後は省略については注意していきます。
じゃんぬねっとさん
返信ありがとうございました。
検索エンジンの「調べ方」により決まる率の高い事が分かってきました。
「LenB + VB.NET」で検索しましたら的確に探せ出せました。
今後は一発でヒットできる様に力を付けて行きたいと思っています。
ありがとうございました。
2006/02/22(Wed) 20:40:23 編集(投稿者)

>Dim sr As System.IO.Stream = webClient.OpenRead(text5.Text)

の直後に

webClient.ResponseHeaders ["Content-Length"]

でコンテンツのバイト数が取得できませんでしたか?
2006/02/22(Wed) 19:03:54 編集(投稿者)

渋木宏明(ひどり)さん
返信下さいまして有り難うございました。遅くなりました。
下記の様に追加しましたら識別子が必要、ResponseHeadersは
System.IO.Streamのメンバでありませんとなりました。
色々と試してはみましたが.NETは基本的な事がまだ良く分かっ
ていませんのでご理解下さい。お手数をお掛けしております。

Dim srRead As New System.IO.StreamReader(sr)
TextBox3.Text = sr.ResponseHeaders ["Content-Length"]
 srRead.Close()
2006/02/22(Wed) 20:53:00 編集(投稿者)
2006/02/22(Wed) 20:51:26 編集(投稿者)

> 下記の様に追加しましたら識別子が必要、ResponseHeadersは
> System.IO.Streamのメンバでありませんとなりました。

webClient.ResponseHeaders の間違いでした。

# 元記事も直しておきました。

ResponseHeaders に Content-Length が含まれていない場合

long contentLength = 0;

if (sr.CanSeek)
{
// WebClient.OpenRead() なら必ずこっち?
contentLength = sr.Length;
}
else
{
// WebClient.OpenReadASync() の時はこっちかも。
using (MemoryStream msr = new MemoryStream())
{
while (sr.Read (buffer, 0, buffer.Length) > 0);
msr.Close();

byte[] array = msr.ToArray();
contentLength = array.Length;
}
}

とした方が良いはずです。(ごめんなさい、C# ですが意図は伝わるでしょう)

# StreamReader の出番はありません ;-p
渋木宏明(ひどり) さん

情報を提供下さいましてありがとうございました。
このサンプルが既にご存知でありましたらすみません。

ファイルのプロパティで 有効期限日時:’ある’場合はサイズがTextBox1.Textに表示されました。
’なし’の場合は表示されませんでした。下記の記述がありました。

ContentLength プロパティは、インターネット リソースからの応答のバイト長を格納します。
ヘッダー情報を含む要求メソッドでは、 ContentLength にはヘッダー情報の長さは含まれません。
とありました。ヘッダー情報に’ある’場合と’なし’の場合の2通りあるのでしょうか?。
’なし’の場合はサイズ表示することはできないと思ってよいでしょうか。?
"http://www.google.co.jp/"は’なし’でした。


http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemnetwebresponseclasscontentlengthtopic.asp


Imports System.Net

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
' Create a 'WebRequest' with the specified url.
Dim myWebRequest As WebRequest = WebRequest.Create("http://www.google.co.jp/")

' Send the 'WebRequest' and wait for response.
Dim myWebResponse As WebResponse = myWebRequest.GetResponse()

TextBox1.Text = myWebResponse.ContentLength


' The ContentLength and ContentType received as headers in the response object are also exposed as properties.
' These provide information about the length and type of the entity body in the response.
Console.WriteLine(ControlChars.Cr + "Content length :{0}, Content Type : {1}", myWebResponse.ContentLength, myWebResponse.ContentType)
myWebResponse.Close()

End Sub

End Class

C#そのものは分かりませんが記述内容は何となくですが分かる気もしますので、これから見てみます。
お手数をお掛けしています。有りがとうございました。
> ファイルのプロパティで 有効期限日時:’ある’場合はサイズがTextBox1.Textに表示されました。
> ’なし’の場合は表示されませんでした。下記の記述がありました。

有効期限とファイルの長さに相関があるとは思えませんが。。。

> とありました。ヘッダー情報に’ある’場合と’なし’の場合の2通りあるのでしょうか?。

「あります」と、以前説明したと思います。

> ’なし’の場合はサイズ表示することはできないと思ってよいでしょうか。?

Content-Length ヘッダが含まれない場合の措置についても既に説明しました。

コンテンツをすべて読み取って、そのバイト数を調べます。
> while (sr.Read (buffer, 0, buffer.Length) > 0);

ここで MemoryStream に書き込まなくちゃ駄目ですね。
なにやってるんだか>じぶん

以下、断片的に書いてもうまくつないでもらえてないみたいなんで、全部書きます。

private void button1_Click(object sender, EventArgs e)
{
WebClient client = new WebClient();

long contentLength = -1;

using (Stream stream = client.OpenRead(this.textBox1.Text))
{
string contentLengthString = client.ResponseHeaders["Content-Length"];

if (contentLengthString != null)
{
contentLength = int.Parse(contentLengthString);
}
else if (stream.CanSeek)
{
contentLength = stream.Length;
}
else
{
byte[] buffer = new byte[4096];

using (MemoryStream memoryStream = new MemoryStream())
{
for (;;)
{
int numberOfBytesRead = stream.Read(buffer, 0, buffer.Length);
if (numberOfBytesRead < 1) break;

memoryStream.Write(buffer, 0, numberOfBytesRead);
}

memoryStream.Close();
contentLength = memoryStream.ToArray().Length;
}
}

stream.Close();
}

if (contentLength < 0)
{
MessageBox.Show("コンテンツの長さ(バイト数)を取得できませんでした。");
}
else
{
MessageBox.Show("コンテンツの長さ(バイト数)は " + contentLength.ToString() + " バイトです。");
}
}
ありがとうございます。
提供下さいました記述は理解できるまでしばらく時間がかかると思いますが、
ご指導を受けることが出来ましたので挑戦してみたいと思います。
今回はいろいろご指導してもらい、心よりお礼を申し上げます。
■No15210に返信(渋木宏明(ひどり)さんの記事)
> webClient.ResponseHeaders ["Content-Length"]
> 
> でコンテンツのバイト数が取得できませんでしたか?

非常に厳密には、単純に Content-Length フィールドの値を取得してはいけな
いかもしれません。

RFC 2616 では、chunked 符号化された転送のように、実体の長さと転送される
データの長さが異なる場合は、Content-Length フィールドを送ってはならない
と規定されています。ですが、それと同時に、符号化された転送でありながら、
Content-Length フィールドも受け取った場合は、Content-Length フィールド
の方を無視しなければならない、とも規定されています。

一方で、符号化されない転送では、Content-Length フィールドの値と実体の長
さが合わない場合は、無視ではなく、通知しなければならない、と規定されて
います。

.NET Framework クラスライブラリの実装は分かりませんが、例外などで通知さ
れることもなく、静かに Content-Length フィールドの値と実体の長さが異な
る場合があるかもしれません。
おおたさん、返信有り難うございました。
とても参考になりました。
今回の参考も考え又、■15214 のサンプルでヘッダー情報にサイズが有る場合は
表示できましたので、一応解決できたとものとしました。今回は多くのご指導、
アドバイスなどをして頂きましてお礼を申し上げます。ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板