- PR -

【ASP.NET】Webサーバ側で複数Excelを圧縮したい

投稿者投稿内容
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-23 15:38
引用:

ひろれいさんの書き込み (2006-03-23 14:48) より:

怒られる前に、訂正します。


怒りはしませんが、(;^-^)

引用:

Dim buf(4096) As SByte


これは、ファイル サイズから求めた方が良いです。

  ファイルのサイズを取得する

今漏れているであろう、ZipEntry に setSize する時にも必要です。
それと、java.util.zip.CRC32 関連が漏れているような気がします。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-03-23 15:39
現状、以下のようなソースにしています。
出来上がる ZIPファイルのサイズはそれっぽいサイズで出来上がるのですが、中を見ると空っぽの状態です。原因は、今のところよく分かりません・・・
現在は、テキストファイルでテストしていますが、Excelファイルでも同じ現象となります。

コード:
Dim filename As String = "data/Test.zip"

ls_Script3.Append("C:\\Test.txt")

Dim bis As New java.io.BufferedInputStream(New java.io.FileInputStream(ls_Script3.ToString))
Dim zos As java.util.zip.ZipOutputStream
zos = New java.util.zip.ZipOutputStream(New java.io.FileOutputStream(Server.MapPath(filename)))

Dim zEntry As java.util.zip.ZipEntry = New java.util.zip.ZipEntry(ls_Script3.ToString)
zEntry.setMethod(zos.DEFLATED)
zos.putNextEntry(zEntry)

Dim buf(2048) As System.SByte

Do
   Dim li_Count As Integer = bis.read(buf)
   If li_Count <= 0 Then
      Exit Do
   Else
      zos.write(buf, 0, li_Count)
   End If
Loop
bis.close()
zos.closeEntry()
zos.flush()
zos.close()



どこか見逃している点がありましたら、指摘していただきたいと思います。
よろしくお願い致します。
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-03-23 16:31
引用:

じゃんぬねっとさんの書き込み (2006-03-23 15:38) より:

これは、ファイル サイズから求めた方が良いです。

今漏れているであろう、ZipEntry に setSize する時にも必要です。
それと、java.util.zip.CRC32 関連が漏れているような気がします。


じゃんぬさん、ありがとうございます。レスがスレ違いで(おやじではございません(^_^;))

色々なページを見ていると、java だとCRC-32チェックサムという設定をかましているようですが、VB.NET だとかまさずにもいけそうですが、どうなんでしょうか。
setSize もかましたり、かまさなかったり、と実例はバラバラのようですが。
JavaでZIP圧縮
VB.NETでZIP圧縮

とりあえず、以下のように修正してみましたが、状況は変わらず、です。
コード:
Dim ls_Script3 As New System.Text.StringBuilder
Dim filename As String = "data/Test.zip"

ls_Script3.Append("C:\\報告書_200603.xls")

Dim bis As New java.io.BufferedInputStream(New java.io.FileInputStream(ls_Script3.ToString))
Dim zos As java.util.zip.ZipOutputStream
zos = New java.util.zip.ZipOutputStream(New java.io.FileOutputStream(Server.MapPath(filename)))

Dim zEntry As java.util.zip.ZipEntry = New java.util.zip.ZipEntry(ls_Script3.ToString)
Dim hFileInfo As New System.IO.FileInfo(ls_Script3.ToString)
Dim lFileSize As Long = hFileInfo.Length
Dim buf(lFileSize) As System.SByte
Dim buf2(lFileSize) As System.SByte
zEntry.setSize(lFileSize)
zEntry.setMethod(ZipEntry.DEFLATED)

Dim crc As New java.util.zip.CRC32
Dim bis2 As New java.io.BufferedInputStream(New java.io.FileInputStream(ls_Script3.ToString))
Do
   Dim li_Count As Integer = bis2.read(buf2)
   If li_Count <= 0 Then
      Exit Do
   Else
      crc.update(li_count)
   End If
Loop
zEntry.setCrc(crc.getValue)
zos.putNextEntry(zEntry)

Do
   Dim li_Count As Integer = bis.read(buf)
   If li_Count <= 0 Then
      Exit Do
   Else
      zos.write(buf, 0, li_Count)
   End If
Loop
bis.close()
zos.closeEntry()
zos.flush()
zos.close()


ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-03-23 16:48
書き忘れていましたが、環境は以下の通りです。

・WindowsXP Professional
・IIS5.1
・.NET Framework1.1
・vjslib 1.1.4322
・VS.NET2003(VB.NET)
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-23 16:53
とりあえず、圧縮ファイルを作るところまでで考えてみましょう。
以下はフリーハンドのソースです、間違いがある可能性があります。

コード:

    Public NotInheritable Class ZipFile

        Public Shared Overloads Sub CompressionFile(ByVal stZipFilePath As String, ParamArray stFilePathes As String())
            Dim oFileOutputStream As java.io.FileOutputStream

            Try
                oFileOutputStream = New java.io.FileOutputStream(stZipFilePath)
                Dim oZipOutputStream As java.util.zip.ZipOutputStream

                Try
                    oZipOutputStream = New java.util.zip.ZipOutputStream(oFileOutputStream)

                    For Each stFilePath As String In stFilePathes
                        CompressionFile(oZipOutputStream, stFilePath)
                    Next stFilePath
                Finally
                    If Not oZipOutputStream Is Nothing Then
                        oZipOutputStream.close()
                    End If
                End Try
            Finally
                If Not oFileOutputStream Is Nothing Then
                    oFileOutputStream.close()
                End If
            End Try
        End Sub

        Private Shared Overloads Sub CompressionFile(ByVal oZipOutputStream As java.util.zip.ZipOutputStream, ByVal stFilePath As String)
            Dim oFileInputStream As java.io.FileInputStream

            Try
                oFileInputStream = New java.io.FileInputStream(stFilePath)
                Dim oBufferdInputStream As java.io.BufferedInputStream

                Try
                    oBufferdInputStream = New java.io.BufferedInputStream(oFileInputStream)

                    Dim iFileSize As Integer = CType(New System.IO.FileInfo(stFilePath).Length, Integer)
                    Dim sbtBuffer As System.SByte() = New System.SByte(iFileSize) {}
                    Dim oCRC32    As New java.util.zip.CRC32()

                    If oBufferdInputStream.read(sbtBuffer, 0, iFileSize) > -1 Then
                         oCRC32.update(sbtBuffer, 0, iFileSize)
                         oZipOutputStream.write(sbtBuffer, 0, iFileSize)
                    End If

                    Dim oZipEntry As New java.util.zip.ZipEntry(System.IO.Path.GetFileName(stFilePath))

                    oZipEntry.setMethod(java.util.zip.ZipEntry.DEFLATED)
                    oZipEntry.setSize(iFileSize)
                    oZipEntry.setCrc(oCRC32.getValue())
                    oZipOutputStream.putNextEntry(oZipEntry)
                    oZipOutputStream.closeEntry()
                Finally
                    If Not oBufferdInputStream Is Nothing Then
                        oBufferdInputStream.close()
                    End If
                End Try
            Finally
                If Not oFileInputStream Is Nothing Then
                    oFileInputStream.close()
                End If
            End Try
        End Sub
    End Class


以下は使用例です。

コード:
                                                                                                                                         
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        ZipFile.CompressionFile("C:\MakiMakiLove.zip", "C:\Book1.xls", "C:\Book2.xls", "C:\Book3.xls")
    End Sub


お手伝いできそうなのはこれくらいです。(;^-^)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-03-23 17:51
引用:

じゃんぬねっとさんの書き込み (2006-03-23 16:53) より:

とりあえず、圧縮ファイルを作るところまでで考えてみましょう。
以下はフリーハンドのソースです、間違いがある可能性があります。

お手伝いできそうなのはこれくらいです。(;^-^)



えっと、出来ました(^_^;)
クラスは上記のまま作成し、呼び出し部分だけカスタマイズしただけですが、問題なく動作しました。思い通り、複数Excelファイルを圧縮できています。

ただ、これは以前から問題として挙がっていたと思いますが、ファイル名に2バイト文字があるとうまくいかなかったです。まあ、これは制限事項ってことでいきます。

本当にありがとうございました。いやぁ、関心しきりですm(_ _)m

じゃんぬさんのクラスのロジックを応用して、コード上(aspx.vb)に記述してみましたが、やはりうまくいきませんでした。私のソースとでは、write と putNextEntry の順番が違いましたので、この辺がくさいかなぁ、と思いましたが、ダメでした。
いまいちスッキリしませんが、皆様お許しくださいませ。
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-03-23 18:49
参考までに。

今回の問題を調査するに当たり、以下のページも参考にしました。

ZIP Entry

ZIP OutputStream
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2006-03-23 20:07
横レスですいません。
J#のZipOutPutStreamは使用したことがないのですが、
スレッドセーフなのでしょうか?

といいますのは、統合アーカイバプロジェクトの○○.DLLは
スレッドセーフではないので、Webサーバアプリケーション側で
使用する場合は、待ち行列に入れるか何らかの排他制御を掛けると
いう意識を持っていたものですから。

J#のクラスはマルチスレッドでも平気?なのでしょうか?

スキルアップ/キャリアアップ(JOB@IT)