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

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

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

Re[2]: Office2007形式のファイルをDBに登録すると破損


(過去ログ 72 を表示中)

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

■41811 / inTopicNo.1)  Office2007形式のファイルをDBに登録すると破損
  
□投稿者/ ごっち (1回)-(2009/09/30(Wed) 18:54:26)

分類:[ASP.NET (VB)] 

こんにちは。

Web画面で選択したファイルをSQL Serverに格納しています。

いままで問題なかったのですが、Office2007形式のファイル(docx/xlsx)を登録し、
ダウンロードすると「ファイルは破損しており、開けません。」のメッセージが表示されてしまいます。
そのまま続行して「開いて修復」を実行するとファイルは開けます。

何がいけないのでしょうか。
お気づきの点があれば教えてください。


■テーブル
CREATE TABLE [dbo].[T_FILE](
[TASK_NO] [nvarchar](10) NOT NULL,
[REPORT_NO] [int] NOT NULL,
[FILENAME] [nvarchar](255) NULL,
[FILEEXT] [nvarchar](10) NULL,
[TYPE] [nvarchar](255) NULL,
[FILEIMG] [varbinary](max) NULL,
CONSTRAINT [PK_T_FILE] PRIMARY KEY CLUSTERED
(
[TASK_NO] ASC,
[REPORT_NO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


■プログラムソース(抜粋)
'添付ファイル登録
Public Function FileToDB(ByVal blnDel As Boolean, ByVal fu As FileUpload, ByVal strTASK_NO As String, ByVal strREPORT_NO As String) As Boolean
If Not String.IsNullOrEmpty(fu.PostedFile.FileName) Then
Dim strSQL As String = _
"INSERT INTO T_FILE(TASK_NO, REPORT_NO, FILENAME, FILEEXT, TYPE, FILEIMG) " & _
"VALUES (@TASK_NO, @REPORT_NO, @FILENAME, @FILEEXT, @TYPE, @FILEIMG)"
Dim objDb As New SqlConnection(GetConnectionString)
Dim objCom As New SqlCommand(strSQL, objDb)
Dim recAffected As Integer
'削除
If blnDel Then
DeleteFile(strTASK_NO, strREPORT_NO)
End If
'パラメータ設定
Dim strFileName As String = Path.GetFileName(fu.PostedFile.FileName)
Dim strExtension As String = strFileName.Substring(strFileName.LastIndexOf(".")).Replace(".", "").ToLower
objCom.Parameters.AddWithValue("@TASK_NO", strTASK_NO)
objCom.Parameters.AddWithValue("@REPORT_NO", strREPORT_NO)
objCom.Parameters.AddWithValue("@FILENAME", strFileName)
objCom.Parameters.AddWithValue("@FILEEXT", strExtension)
objCom.Parameters.AddWithValue("@TYPE", fu.PostedFile.ContentType)
'ファイルを入力ストリーム経由でbyte配列に読み込む
Dim aryData(fu.PostedFile.ContentLength) As Byte
fu.PostedFile.InputStream.Read(aryData, 0, fu.PostedFile.ContentLength)
objCom.Parameters.AddWithValue("@FILEIMG", aryData)
'登録
objDb.Open()
recAffected = objCom.ExecuteNonQuery()
objDb.Close()
End If
Return True
End Function

'添付ファイル削除
Public Function DeleteFile(ByVal strTASK_NO As String, ByVal strREPORT_NO As String) As Boolean
Dim strSQL As String = _
"DELETE FROM T_FILE " & _
"WHERE TASK_NO = @TASK_NO " & _
" AND REPORT_NO = @REPORT_NO"
Dim objDb As New SqlConnection(GetConnectionString)
Dim objCom As New SqlCommand(strSQL, objDb)
Dim recAffected As Integer
'パラメータ設定
objCom.Parameters.AddWithValue("@TASK_NO", strTASK_NO)
objCom.Parameters.AddWithValue("@REPORT_NO", strREPORT_NO)
'削除
objDb.Open()
recAffected = objCom.ExecuteNonQuery()
objDb.Close()
Return True
End Function

引用返信 編集キー/
■41823 / inTopicNo.2)  Re[1]: Office2007形式のファイルをDBに登録すると破損
□投稿者/ やじゅ (1354回)-(2009/09/30(Wed) 22:22:37)
やじゅ さんの Web サイト
No41811 (ごっち さん) に返信
> Web画面で選択したファイルをSQL Serverに格納しています。
> いままで問題なかったのですが、Office2007形式のファイル(docx/xlsx)を登録し、
> ダウンロードすると「ファイルは破損しており、開けません。」のメッセージが表示されてしまいます。
> そのまま続行して「開いて修復」を実行するとファイルは開けます。

元のファイルとダウンロードしたファイルとでバイナリ比較してみたらどうでしょう。
登録うんぬんが悪い気はしませんね。
引用返信 編集キー/
■41829 / inTopicNo.3)  Re[1]: Office2007形式のファイルをDBに登録すると破損
□投稿者/ 魔界の仮面弁士 (1331回)-(2009/09/30(Wed) 23:19:26)
No41811 (ごっち さん) に返信
> Web画面で選択したファイルをSQL Serverに格納しています。
ASP.NET は専門外なので、はずしているかも知れませんが:


> 'ファイルを入力ストリーム経由でbyte配列に読み込む
> Dim aryData(fu.PostedFile.ContentLength) As Byte
fu.PostedFile.ContentLength からは、ファイルのサイズ(バイト数)が得られるのですよね。

配列宣言時には、「インデックスの上限値」を指定する事になっています。

たとえば「Dim aryData(10) As Byte」の場合、aryData(0)〜aryData(10) までの
計11バイトの領域が確保されるはずですが、その点は大丈夫でしょうか?
引用返信 編集キー/
■41838 / inTopicNo.4)  Re[2]: Office2007形式のファイルをDBに登録すると破損
□投稿者/ ごっち (2回)-(2009/10/01(Thu) 09:16:26)
やじゅさん、魔界の仮面弁士さん

ありがとうございます。
バイナリエディタで確認するのを忘れていました。

確認すると1バイト余計に付与されています。
Office2007になってから厳密にチェックするようになって、既存バグが出たということです。

Dim aryData(fu.PostedFile.ContentLength) As Byte
ここのサイズが大きいのが原因でした。

ありがとうございました。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -