- - PR -
【ASP】バイナリデータのDB読み書き
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-11-01 17:31
ある入力フォームでファイルを添付してDB(SQLServer)にバイナリデータ
を書き込むプログラムを作成しています。 添付ファイルをアップロード後、その後対象ファイルをダウンロードして テストをしてみました。 Excel、Word、exe、zip、lzh 等の一般的なファイルは問題なく開いたのですが、 xdw という拡張子のファイル (富士ゼロックス社製のドキュワークスと呼ばれるソフトのファイルです) を開くとファイルが壊れてしまって開かなくなっていました。 ファイルのアップ前とダウン後のサイズを確認すると、 元ファイルのサイズ サイズ:156 KB (159,999 バイト) ディスク上のサイズ:160 KB (163,840 バイト) アップロードしてダウンロードしたファイルサイズ サイズ:156 KB (160,000 バイト) ディスク上のサイズ:160 KB (163,840 バイト) となっており、どうやら1バイトだけ増えています。 ただ、圧縮した状態でアップし、ダウンロードすると 解凍後問題なく開きました。 私はバイナリデータを扱った経験が無くいろいろなサンプルを参考にして 作ったのですが、どなたかご教授頂ければ幸いです。 以下がソースです。 ファイルアップロード Protected Sub btnInsert_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInsert.Click Dim objDB As New SqlConnection("Data Source=XXX;User ID=XXX;Password=XXX;Initial Catalog=XXX") Dim objCom As New SqlCommand("Insert Into TEMPTBL (ID,ファイルタイプ,ファイル名,添付FILE) " & _ "Values (@ID,@FileType,@FileName,@Tenpu)", objDB) objCom.Parameters.Add("@FileName", Path.GetFileName(Me.upFile.PostedFile.FileName)) objCom.Parameters.Add("@FileType", Me.upFile.PostedFile.ContentType) Dim aryData(Me.upFile.PostedFile.ContentLength) As Byte Me.upFile.PostedFile.InputStream.Read(aryData, 0, Me.upFile.PostedFile.ContentLength) objCom.Parameters.Add("Tenpu", aryData) objDB.Open() objCom.ExecuteNonQuery() objDB.Close() End Sub ファイルダウンロード Protected Sub btnDownload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim intID As Integer = Me.GridViewMessage.SelectedValue Dim objRs As SqlDataReader Dim objDB As New SqlConnection("Data Source=XXX;User ID=XXX;Password=XXX;Initial Catalog=XXX") Dim objCom As New SqlCommand("Select ファイル名,ファイルタイプ,添付FILE From TEMPTBL Where ID=" & intID, objDB) objDB.Open() objRs = objCom.ExecuteReader() If objRs.Read Then Response.HeaderEncoding = Text.Encoding.GetEncoding("shift-jis") Response.ContentType = "application/octet-stream" Response.AddHeader("Content-Disposition", " attachment;filename=" & HttpUtility.UrlEncode(CType(objRs.Item(0), String))) Response.Flush() Response.BinaryWrite(CType(objRs.Item(2), Byte())) End If objDB.Close() Response.End() End Sub | ||||||||
|
投稿日時: 2006-11-01 18:02
先程のファイル、アップ前とアップ後のファイルを
バイナリエディタで開いて確認してみました。 するとアップ後のファイルには1バイト分だとは思うのですが、 データの最後の0f欄に 00が入っていました。 元のファイルの同じ場所はブランクになっていました。 どなたかよろしくお願い致します。 | ||||||||
|
投稿日時: 2006-11-01 22:05
可能なら、適当な 159,999 バイトのファイルを作って、試してみてください。
コードは読んでいませんが、他のファイルが処理できているのなら、何らかの条件で SQL Server とのやりとりの間で、余分なデータが追加されている可能性があります。 また、アップロードしたファイルを、DB に格納せずに、そのままファイルに格納してみてください。または、アップロードされたファイル(サーバ上)のバイト数は、どうなっていますか。 _________________ | ||||||||
|
投稿日時: 2006-11-01 23:40
NAL-6295です。
たぶん原因はここだと思います。 C#なら、指定したサイズの配列になりますが、 VB.NETの場合は、指定したIndexまでの配列になります。 Indexは0オリジンなので、Me.upFile.PostedFile.ContentLength+1分の配列を作ってしまうわけです。 だから
としたらうまく行くのではないでしょうか。 #VB.NETとC#を行き来しているとたまにやらかします。 [ メッセージ編集済み 編集者: NAL-6295 編集日時 2006-11-01 23:41 ] | ||||||||
|
投稿日時: 2006-11-02 13:40
JittaさんNAL-6295さん、返信ありがとうございます。
なんとかNAL-6295さんの方法で解決できました。 私はこの Me.upFile.PostedFile.ContentLength を使うのは今回初めてでして、ContentLengthという最後の標記を 見て、長さを取得しているんだなと勝手な解釈をしていました。 しかも長さなのに0オリジンとは、某携帯キャリアではありませんが、 「予想外です」 対象のファイルをアップロード後にダウンロードしてデータ容量も あっており、バイナリエディタで確認しても最後に00は付いていませんでした。 しかしExcelやその他のファイルでも同じ状態になっていたはずなのにExcel等では 開く事が出来たのが今となっては不思議でしょうがありません。 無事に解決できて良かったです。 本当にありがとうございました。 | ||||||||
|
投稿日時: 2006-11-02 14:05
いやそうではなくて、配列の定義に指定する値の扱いが違うという話なのですよ。
って読んでくれるのか判らないけど。。。 [VB.NET] Dim c(5) As Integer '要素0から要素5までの6個の器をつくる [C#] int[] c = new int[5]; //要素0から要素4までの5個の器をつくる | ||||||||
|
投稿日時: 2006-11-02 14:06
ContentLengthに入っているのは長さですよ。 配列の宣言に問題があったのです。 予想外ではなく、仕様通りにやればちゃんとできます。 0オリジンが予想外という事は、今まで配列は1から参照していたのですか? 私が前述した
というのは、配列の宣言の話です。 ContentLengthは何も関係ありません。 一度、対象言語の仕様を理解されてはいかがでしょうか? | ||||||||
|
投稿日時: 2006-11-02 14:59
みなさま、大変申し訳ありません。
書いた後に気づきました・・・。 配列の話の事ですよね aryData(ここですよね) 送信後、自分の勘違いに気づき、 顔が真っ赤になりました。 失礼致しました。 |
1