当我将新字符串(byte[])放入数据库和从数据库中取出时,它会给出不同的结果



如果打印new String(data)的输出,在将字节数组保存到数据库之前,它会返回一个可读字符串,如";foobar";但当我把它从数据库中取出后,new String(data)会读起来像一堆胡言乱语,比如";9238929384739427349327…";。这里有太多的部分,我只想把它们全部列出来。我使用eclipselink,我的数据列定义为:

@Lob
@Column(name = "data")
private byte[] data;

如果我运行这个代码:

public static void main(String[] args) {
    System.out.println(Charset.defaultCharset());
}

输出CCD_ 3。

我的数据库定义为:

CREATE DATABASE project_trunk
  WITH OWNER = project
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'English_United States.1252'
       LC_CTYPE = 'English_United States.1252'
       CONNECTION LIMIT = -1;

我也在这样定义的数据库上尝试过:

CREATE DATABASE project_trunk
  WITH OWNER = project
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'en_US.UTF-8'
       LC_CTYPE = 'en_US.UTF-8'
       CONNECTION LIMIT = -1;

问题仍然存在。

我认为发生的事情是我的数据库与我的应用服务器有不同的编码。当我把东西放进数据库并再次取出时,它会以错误的方式解码,所以看起来像胡言乱语。我有什么线索吗?

现在,当谈到这个问题的解决方案时,我有点困惑。我认为我应该做的是将我的appserver的文件编码更改为与数据库相同。我使用的是Glassfish 2.1.1。当我转到CCD_ 4并将Locale设置为";UTF8";或";UTF-8";它告诉我需要重新启动。在我重新启动glassfish之后,该字段仍然是空白的,并且我仍然得到错误。我想也许这并不能拯救财产。我会手动将它放在配置文件中,但我不知道该放在哪里或放什么。

或者,我尝试用ENCODING="WIN1250"创建我的数据库,但当我这样做时,它说我的LC_CTYPE需要是";WIN1252";。当我将LC_CTYPE设置为"0"时;WIN1252";它说编码不存在。


我在这上面花了很多时间,我想知道我是否在这里有所收获。我的";appserver和db之间的不同步编码;听起来正确,还是我在转移注意力?如果有人能帮我弄清楚如何更改玻璃鱼2.1.1的设置,那也会很有帮助。感谢

编辑:人们问我为什么把字符串存储为原始字节。这并不完全是我在做的,有时原始字节代表图像、pdf或二进制文件,有时是文本。我的测试是插入一个纯文本字符串并将其拉出以确保其正确保存。这个测试通过了我们在linux上的CI服务器。

第二版:我被要求展示原始二进制输入和原始二进制输出。

预期:[11610410511511321051511321971101110111011101111632,9732,83,116114,105110,103]

实际:[60,54,56,54,57,55,51,50,48,54,55,55,50,50,54,100,55,57,48,51,49,55,52,52,54,49,51,54,54,50,100,54,53,101,55

我给我的同事做了同样的测试,他在mac上检查字节,结果通过了。

有时原始字节表示图像、pdf或二进制文件,有时是文本

好吧,那么你不应该把它们作为文本存储。

不管当前出现了什么问题,即使您可以将其用于实际上是文本的数据,稍后也会出现问题。

如果必须将任意二进制数据存储为文本,则应该使用base64对其进行编码,这样就可以毫无问题地返回到原始二进制数据。(你只需要能够传输ASCII字符串,这通常相当容易。)Base64有很多第三方库;我喜欢这个独立的公共领域。

或者,将数据作为二进制数据存储在数据库中,例如使用bytea数据类型的字段。这样就不需要做任何转换工作:只需要将它作为字节数组放入数据库,然后作为字节数组输出即可。

编辑:好吧,看起来您正在返回二进制数据的十六进制表示,但使用ASCII。这很奇怪。

事实证明,这是由PostgreSQL在版本9和版本8中的工作方式引起的。我的大多数同事都在使用版本8,但我最近买了一台新电脑,所以我使用了最新的PostgreSQL。

您需要将output_bytea设置为"escape"。

使用jpa 从postgres读取byte[]时,长度几乎是原来的两倍

不过,我在那里没有找到足够的答案,但我在邮件列表中找到了这个,它解决了我的问题:http://www.postgresql.org/message-id/AANLkTikkE-jQ9srZ9VL1JuJ5h=UCutx8ZLim+OfQ1T4z@mail.gmail.com

尊敬的名单,

字节输出格式在9.0中从escape到hex的最新更改明显中断流行的持久会话处理perl模块,如Apache::session::Postgres它将经过酸洗的数据结构存储在db表的字节列中。很难从引发的异常中猜测根本原因所述模块。通过添加postgresql.conf中的byta_output='scape'并发出pg_ctl重载。

例如,在RT应用程序中,错误为:错误:RT无法存储您的会话。这可能意味着目录/bah/bah/foo/bar不是可写或数据库表丢失或损坏

RegdsRajesh Kumar Mallah。

相关内容

  • 没有找到相关文章

最新更新