2

我正在使用 MSSQL 2005。

我有包含我的zip文件内容的StringIO对象。

这是我获取 zip 二进制数据的方法:

    stringio = Zip::ZipOutputStream::write_buffer do |zio|
        Eclaim.find_by_sql("SET TEXTSIZE 67108864")
        zio.put_next_entry("application.xml")
        #zio.write @claim_db[:xml]
        biblio = Nokogiri::XML('<?xml version="1.0" encoding="utf-8"?>' + @claim_db[:xml], &:noblanks)
        zio.write biblio.to_xml

        builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
            xml.documents {
                docs.where("ext not in (#{PROHIBITED_EXTS.collect{|v| "'#{v}'"}.join(', ')})").each{|doc|
                    zio.put_next_entry("#{doc[:materialtitle_id]}.#{doc[:ext]}")
                    zio.write doc[:efile]

                    xml.document(:id => doc[:materialtitle_id]) {
                        xml.title doc[:title]
                        xml.code doc[:code]
                        xml.filename "#{doc[:materialtitle_id]}.#{doc[:ext]}"
                        xml.extname doc[:ext]
                    }

                }
            }
        end

        zio.put_next_entry("docs.xml")
        zio.write builder.to_xml
    end

    stringio

在我的控制器中,我尝试:

data.rewind
@claim.docs.create(
    :title => 'Some file',
    :ext => 'zip',
    :size => data.length,
    :receive_date => Time.now,
    :efile => data.sysread
)

但是 Rails 抱怨UTF-8 中的字节序列无效

请帮助我。

4

3 回答 3

6

如果流配置为 UTF-8 流,则不能写入压缩二进制文件(可能包含任何值)。

我认为,data在写入之前设置为二进制流:

data.force_encoding "ASCII-8BIT"

可能有帮助。

于 2012-05-13T13:25:59.050 回答
1

什么是抱怨、ruby、ActiveRecord 或 SQL Server?我的猜测是 SQL Server。确保数据库中 efile 字段的数据类型是二进制 BLOB。

于 2012-05-13T10:55:30.317 回答
1

您应该将问题分解为组成部分,并对较小的单元进行故障排除。消除复杂性,直到找到问题的根源。例如,您是否尝试过简单Document.create地使用控制台中的属性来消除您的控制器代码可能存在错误的可能性?类似的东西Document.create :efile => File.read('sometiny.zip'),然后从那里开始。

假设工作或中断,您的支持请求要简单得多,而且噪音与问题的比率也更低。现在我怀疑你的控制器代码,而不是 SQL Server 适配器或连接模式,因为我都已经测试了简单的二进制数据。假设上述方法不起作用,您可以转向检查较小的组件。

例如,efile列的数据类型是什么?在控制台中执行此操作以找出答案,Document.columns_hash['efile']然后查看@sql_type. 它是合适的varbinary(max)吗?

从那里继续,您在 SQL Server 适配器 TinyTDS 中使用什么连接模式?默认情况下,TinyTDS 会根据需要将所有内容转换为 UTF8,并且非常聪明。我对它进行了从二进制到许多不同编码的所有测试。顺便说一句,如果您使用的是 TinyTDS,您是否确保使用 libiconv 编译了 FreeTDS,以便它可以正确完成所有这些工作?tsql -C假设您的路径中有 FreeTDS 的二进制文件,您可以通过在控制台中执行以下操作轻松检查。这应该输出几行,寻找“iconv library:yes”。还要确保您运行的是 0.91 或更高版本!

最后,一点建议, SET TEXTSIZE 在那里是错误的。您只想在每个连接中执行一次。见这里https://github.com/rails-sqlserver/activerecord-sqlserver-adapter#configure-connection--app-name

于 2012-05-13T14:39:49.977 回答