C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

リンク先のファイル形式を調べる方法

[トピック内 23 記事 (1 - 20 表示)]  << 0 | 1 >>

■85641 / inTopicNo.1)  リンク先のファイル形式を調べる方法
  
□投稿者/ スマスマ (1回)-(2017/11/12(Sun) 21:29:17)

分類:[.NET 全般] 

HTMLファイルを解析して
そのファイル内のリンクから自動でファイルを保存するプログラムをVBで作りたいのですが


リンクに拡張子がある場合には
ファイル形式を知ることができますが、
ない場合にはどのようにしてファイル形式を調べれば良いですか?

Internet explorerで
リンクを右クリックして
「対象をファイルに保存する」を選択すると
拡張子がなくとも自動でフォーマットを識別して
拡張子をつけてくれるのですが、
これはVBではどのように書けば良いですか?







引用返信 編集キー/
■85642 / inTopicNo.2)  Re[1]: リンク先のファイル形式を調べる方法
□投稿者/ Azulean (898回)-(2017/11/12(Sun) 22:04:51)
No85641 (スマスマ さん) に返信
> リンクに拡張子がある場合には
> ファイル形式を知ることができますが、
> ない場合にはどのようにしてファイル形式を調べれば良いですか?

Content-Type ヘッダーでファイルを識別するか、Content-Disposition ヘッダーで指示されるファイル名を使うかでしょうね。
後者を優先しつつ、後者がない場合は前者の Content-Type で得られる MIME タイプから拡張子を決めるぐらいでしょうか。

とりあえず、後者の話はこの辺かな?
http://www.atmarkit.co.jp/fdotnet/dotnettips/618downnoname/downnoname.html
引用返信 編集キー/
■85643 / inTopicNo.3)  Re[2]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (4回)-(2017/11/12(Sun) 22:31:09)
No85642 (Azulean さん) に返信

ありがとうございます。

以下のようにして試してみたのですが
disposがnothingとなっており、ファイル名を取得することができません。
他のURLも試してみましたがうまくいきませんでした
何が問題でしょうか?


    Sub main2()


        Dim url As String = "http://www.atmarkit.co.jp/fdotnet/dotnettips/618downnoname/downnoname.html"

        Dim req As HttpWebRequest _
          = CType(WebRequest.Create(url), HttpWebRequest)
        Dim res As HttpWebResponse _
          = CType(req.GetResponse(), HttpWebResponse)

        Dim fileName As String = "download.tmp"

        ' ヘッダ情報からファイル名の取得
        Dim dispos As String = res.Headers("Content-Disposition")

        If Not String.IsNullOrEmpty(dispos) Then

            ' filename=<ファイル名>の抜き出し
            Dim re As New Regex(
              "filename\s*=\s*           " &
              "(?:                       " &
              "  ""(?<filename>[^""]*)"" " &
              "  |                       " &
              "  (?<filename>[^;]*)      " &
              ")                         " _
              , RegexOptions.IgnoreCase _
              Or RegexOptions.IgnorePatternWhitespace)

            Dim m As Match = re.Match(dispos)
            If m.Success Then
                fileName = m.Groups("filename").Value
            End If
        End If

        ' ファイルのダウンロード
        Using st As Stream = res.GetResponseStream()
            Using fs As New FileStream(fileName, FileMode.Create)
                Dim buf(1024) As Byte
                Dim count As Integer = 0
                Do
                    count = st.Read(buf, 0, buf.Length)
                    fs.Write(buf, 0, count)
                Loop While count <> 0
            End Using
        End Using
        res.Close()
    End Sub



引用返信 編集キー/
■85644 / inTopicNo.4)  Re[3]: リンク先のファイル形式を調べる方法
□投稿者/ Azulean (899回)-(2017/11/12(Sun) 22:50:00)
No85643 (スマスマ さん) に返信
> 以下のようにして試してみたのですが
> disposがnothingとなっており、ファイル名を取得することができません。
> 他のURLも試してみましたがうまくいきませんでした
> 何が問題でしょうか?

先にも書きましたが、存在しない場合もあるということです。
今回の URL だと、サーバー側としてもダウンロードファイル名を指定する必要がありませんからね。

Content-Disposition はサーバーがこのファイル名で保存して欲しいと希望を出す場合だけ、ついてくると思ってください。
引用返信 編集キー/
■85645 / inTopicNo.5)  Re[4]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (6回)-(2017/11/12(Sun) 22:57:43)
No85644 (Azulean さん) に返信

ありがとうございます。
そうでしたか・・

それでは、前者の
Content-Type ヘッダーでファイルを識別する方法もお教えいただけないでしょうか?
よろしくお願いいたします。
 
引用返信 編集キー/
■85646 / inTopicNo.6)  Re[5]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (7回)-(2017/11/12(Sun) 23:09:50)
検索して調べたところ
https://webbibouroku.com/Blog/Article/asp-mimetype

このページが見つかったのですが
この方法のことでしょうか?

一応、試してみましたが取得できているようなのですが
 
引用返信 編集キー/
■85647 / inTopicNo.7)  Re[6]: リンク先のファイル形式を調べる方法
□投稿者/ Azulean (900回)-(2017/11/12(Sun) 23:28:22)
No85646 (スマスマ さん) に返信
> 検索して調べたところ
> https://webbibouroku.com/Blog/Article/asp-mimetype
>
> このページが見つかったのですが
> この方法のことでしょうか?
>
> 一応、試してみましたが取得できているようなのですが

冷たい返事をすると「取得できているならよいじゃないですか」になってしまうので、何を期待して、どうなったかをわかるように書いた方がいいですよ。
MIME タイプから拡張子を判別する、かんたんな方法があるかは存じません。
地道にやるなら、上記ページに書いてある、type で一致する拡張子を探せばよいだけかと思いますが。
引用返信 編集キー/
■85648 / inTopicNo.8)  Re[7]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (9回)-(2017/11/12(Sun) 23:49:48)
ありがとうございます。

うまくいきました。

教えてくださった通り、
後者の方法でファイルパスを取得できるか調べた後に、前者の方法を使いたいと思います。
ここで問題が発生したのですが
Dim res As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)

というところで、URLが無効だったり、リンク切れだったりすると
エラーが出てプログラムが終了してしまうのですが
予め、URLが生きているかどうか調べるにはどのようにしたら良いですか?
 
引用返信 編集キー/
■85649 / inTopicNo.9)  Re[8]: リンク先のファイル形式を調べる方法
□投稿者/ Azulean (901回)-(2017/11/13(Mon) 00:00:38)
2017/11/13(Mon) 00:01:34 編集(投稿者)

No85648 (スマスマ さん) に返信
> 予め、URLが生きているかどうか調べるにはどのようにしたら良いですか?

そんな方法はありません。

一般論として、プログラムを組んでいると、「事前にチェックしたい」と思うこともありますが、その事前にチェックした時点と、実際に処理を始めた時点で状態が変わることがあり得るため、事前チェックは効果がないことがあります。
よって、例外処理(エラー処理)が必要です。

(事前チェックが不要とまでは言いませんが、事前チェックが万能ではないということを言いたいのです。もっとも、HTTP の場合は実際に取りに行った際のエラーチェックの方が良いとは思いますが…)


> というところで、URLが無効だったり、リンク切れだったりすると
> エラーが出てプログラムが終了してしまうのですが

ということで、例外処理として Try Catch を書いてください。
Try Catch を知らない場合は、Try Catch と HttpWebResponse を組み合わせて探せば見つかるのではないかと思います。
引用返信 編集キー/
■85650 / inTopicNo.10)  Re[1]: リンク先のファイル形式を調べる方法
□投稿者/ WebSurfer (1337回)-(2017/11/13(Mon) 00:02:36)
No85641 (スマスマ さん) に返信

クライアント側でファイルの種類を識別する方法は応答ヘッダに含まれる Content-Type か
Content-Disposition の filename に指定される拡張子しかないです。

Web サイトが a 要素をクリックしてダウンロードさせるようになっている場合は、src 属性
に指定されているリソースのファイル名の拡張子で分かるということもあるかもしれませんが、
ブラウザでそれをクリックしてダウンロードした場合、ブラウザはそんなものは見てません。

ブラウザは Content-Type か Content-Disposition の filename に指定される拡張子しか見
てません。(どちらを見るかはブラウザによって異なります)

src 属性に指定された url に拡張子がないというケースは質問者さんが経験された通りで、
そもそも url の情報で判断できるものではないです。

どういうプログラムを作っているか質問に書いてないので分かりませんが(そういう情報は
最初の質問にちゃんと書きましょうね)、何にせよ何らかの手段で応答ヘッダを調べて対応
するほかないと思います。
引用返信 編集キー/
■85651 / inTopicNo.11)  Re[1]: リンク先のファイル形式を調べる方法
□投稿者/ WebSurfer (1338回)-(2017/11/13(Mon) 11:34:49)
No85641 (スマスマ さん) に返信

ご参考に IE がどのようにファイル名(拡張子を含む)を判断しているかという記事
を紹介します。(注:IE のみです。他のブラウザでは異なります)

ファイルのダウンロードダイアログで表示されるファイル名の命名規則
https://support.microsoft.com/ja-jp/help/436153

記事には明記されていませんが、優先順位は番号の通り 1.Content-Disposition: ヘ
ッダ、2. Content-Type ヘッダの順になります。

また、2. Content-Type ヘッダについてはレジストリの情報と照合するのですが、具
体的には以下の記事のようにしているようです。

ダウンロードの際の拡張子
http://surferonwww.info/BlogEngine/post/2016/06/12/extension-of-downloaded-file.aspx
引用返信 編集キー/
■85657 / inTopicNo.12)  Re[2]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (11回)-(2017/11/13(Mon) 13:16:52)

ありがとうございます。

https://dobon.net/vb/dotnet/internet/httpstatuscode.html
このページにあるようにして
Tryを試してみたのですが



Tryと
res = CType(req.GetResponse(), HttpWebResponse)
を組み合わせて使うと、
エラーがあった場合に、ものすごく時間がかかってしまいます。

一方で、
Tryと
wc.DownloadFile(url, path)
を組み合わせて使っても、
エラーがあったとしてもそれほど時間がかかりません。

それで思ったのですが
いったん

Tryと
wc.DownloadFile(url, path)
で適当なファイル名でファイルをDLした後に、
DL出来たファイルにのみ
res = CType(req.GetResponse(), HttpWebResponse)
を使って、ファイル名の取得を試みて
後からファイル名を変更すれば良いのではないかと思いました。

こういう使い方もありなのでしょうか?


引用返信 編集キー/
■85666 / inTopicNo.13)  Re[3]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (12回)-(2017/11/13(Mon) 21:04:24)





問題ないようなので、
この方法でいきたいと思います

ところで、すいませんが別の質問をさせてください。

リンクを右クリックメニューから保存しようとするとファイル名が表示されるのに
Content-Disposition ヘッダーではファイル名を取得できないものがよくあります。

例えば、

https://www.alc.co.jp/business/

というページです。

https://www.alc.co.jp/

このページのの一番上にある「ビジネス英語」というところに
このリンクがあるのですが
右クリックして保存しようとすると
business.htm
というファイル名が表示されます。

このファイル名は一体どのようにして取得すれば良いのでしょうか?



引用返信 編集キー/
■85668 / inTopicNo.14)  Re[4]: リンク先のファイル形式を調べる方法
□投稿者/ Azulean (902回)-(2017/11/13(Mon) 22:33:56)
2017/11/13(Mon) 22:39:05 編集(投稿者)

No85657 (スマスマ さん) に返信
> Tryと
> wc.DownloadFile(url, path)
> で適当なファイル名でファイルをDLした後に、
> DL出来たファイルにのみ
> res = CType(req.GetResponse(), HttpWebResponse)
> を使って、ファイル名の取得を試みて
> 後からファイル名を変更すれば良いのではないかと思いました。
>
> こういう使い方もありなのでしょうか?

なしでしょう。
二重にダウンロードしようとしてますよね…。
サーバー側に負担をかけるかもしれませんし、サーバー側のアクセスログにも二重ダウンロードが記録されます。
また、DownloadFile 時点で生存していても、GetResponse 時点でなくなっていればエラーになります。

No85666 (スマスマ さん) に返信
> このファイル名は一体どのようにして取得すれば良いのでしょうか?

単に URL の末尾に Content-Type に基づいた拡張子をつけているだけでは?
引用返信 編集キー/
■85671 / inTopicNo.15)  Re[4]: リンク先のファイル形式を調べる方法
□投稿者/ Jitta (339回)-(2017/11/14(Tue) 08:53:20)
No85666 (スマスマ さん) に返信
>
> 例えば、
>
> https://www.alc.co.jp/business/
>
> というページです。
>
> https://www.alc.co.jp/
>
> このページのの一番上にある「ビジネス英語」というところに
> このリンクがあるのですが
> 右クリックして保存しようとすると
> business.htm
> というファイル名が表示されます。
>
> このファイル名は一体どのようにして取得すれば良いのでしょうか?
>
>
>

取れていません。
リクエストは、ディレクトリに対して行われています。
ウェブサーバーの設定で、ディレクトリに対するリクエストに応えるファイル名があります。
IISならdefault.aspxとかdefault.htmlとか。
これが指定されていないので、クライアント側で勝手に作っていると判断されます。
引用返信 編集キー/
■85697 / inTopicNo.16)  Re[5]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (13回)-(2017/11/15(Wed) 09:40:14)

ありがとうございます。

もう少し質問させてください。



Content-Type ヘッダーでファイルを識別する方法に関してですが

https://webbibouroku.com/Blog/Article/asp-mimetype

このページにある方法を使っていたのですが
よく読んでみると
「拡張子から MIEM TYPE を取得する方法」
と書かれてあります。
拡張子が知りたくてMIMEを調べようとしているのに
なぜか拡張子からMIMEの調べ方、あるのですが、
これはどういうことですか?
URL上には拡張子が書かれていないが、実際のファイルには書かれてあるのですが
それを使っているのでしょうか?
しかしそれなら拡張子をそのまま教えてくれれば良いと思うのですが。

あと、
http://chaichan.lolipop.jp/vbtips/VBMemo2009-11-25.htm
別の方法だとファイルを解析してMIMEを調べるようなのですが、
この方法だと一度、ファイルをDLしてから解析することになるのしょうか?

DL前に拡張子を知りたい場合には、

https://webbibouroku.com/Blog/Article/asp-mimetype

を使うべきなのでしょうか?



引用返信 編集キー/
■85714 / inTopicNo.17)  Re[6]: リンク先のファイル形式を調べる方法
□投稿者/ Jitta (340回)-(2017/11/15(Wed) 14:33:09)
No85697 (スマスマ さん) に返信
>
> Content-Type ヘッダーでファイルを識別する方法に関してですが
>
> https://webbibouroku.com/Blog/Article/asp-mimetype
>
> このページにある方法を使っていたのですが
> よく読んでみると
> 「拡張子から MIEM TYPE を取得する方法」
> と書かれてあります。

あなたが作っているのはなんですか?
クライアント側ではないですか?
そのページに書いてあるのは、サーバー側の話です。



> あと、
> http://chaichan.lolipop.jp/vbtips/VBMemo2009-11-25.htm
> 別の方法だとファイルを解析してMIMEを調べるようなのですが、
> この方法だと一度、ファイルをDLしてから解析することになるのしょうか?
>

ダウンロードするかどうかはともかく、
FileStream側の扱える場所になければならないでしょうね。
引用返信 編集キー/
■85716 / inTopicNo.18)  Re[7]: リンク先のファイル形式を調べる方法
□投稿者/ スマスマ (14回)-(2017/11/15(Wed) 15:22:13)
No85714 (Jitta さん) に返信


これはサーバー側の話でしたか・・

クライアント側から、
MIMEタイプを調べるにはどのようにしたら良いですか?

引用返信 編集キー/
■85717 / inTopicNo.19)  Re[8]: リンク先のファイル形式を調べる方法
□投稿者/ PANG2 (199回)-(2017/11/15(Wed) 15:42:12)
2017/11/15(Wed) 15:54:36 編集(投稿者)
2017/11/15(Wed) 15:43:59 編集(投稿者)

No85716 (スマスマ さん) に返信
> クライアント側から、
> MIMEタイプを調べるにはどのようにしたら良いですか?

(1)MIMEタイプの取得

Content-Type ヘッダーを読む。
HTTPヘッダを読む方法は、
No85643 に既出。

もしくは、
HttpWebResponse.ContentType プロパティ

(2)MIMEタイプから拡張子の取得

レジストリの HKEY_CLASS_ROOT\MIME\Database\Content Type 以下を見る。
No85651 に既出。
引用返信 編集キー/
■85718 / inTopicNo.20)  Re[9]: リンク先のファイル形式を調べる方法
 
□投稿者/ スマスマ (15回)-(2017/11/15(Wed) 16:13:27)
No85717 (PANG2 さん) に返信

No85643 の方法は、

Content-Type ヘッダーではなく、Content-Disposition ヘッダーで読む方法ではないでしょうか?
Content-Type ヘッダーの方法をお教えくださいませ。
 
引用返信 編集キー/

このトピックをツリーで一括表示

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -