Java 无法在Android版本9上使用编码UTF-16LE

Java 无法在Android版本9上使用编码UTF-16LE,java,android,encoding,character-encoding,utf-16le,Java,Android,Encoding,Character Encoding,Utf 16le,我有一个创建csv文件的应用程序。然后由excel makro导入该文件。makro需要使用UTF-16LE编码对文件进行编码。问题是,我无法在某些设备上使用这种编码 到目前为止,我使用字符集UTF-16创建该文件。当我用notepad++打开文件时,它显示文件是用UTF-16LE编码的。现在我有了一个新设备,当我用它创建csv文件时,notepad++向我显示编码为UTF-16BE。因此,我在尝试使用excel makro导入文件时出错 我试图将编码指定为UTF-16LE,根据android的

我有一个创建csv文件的应用程序。然后由excel makro导入该文件。makro需要使用UTF-16LE编码对文件进行编码。问题是,我无法在某些设备上使用这种编码

到目前为止,我使用字符集UTF-16创建该文件。当我用notepad++打开文件时,它显示文件是用UTF-16LE编码的。现在我有了一个新设备,当我用它创建csv文件时,notepad++向我显示编码为UTF-16BE。因此,我在尝试使用excel makro导入文件时出错

我试图将编码指定为UTF-16LE,根据android的标准,它应该是一个有效的字符集。但是记事本++无法识别我的文件编码,excel makro无法读取(对于旧设备和新设备)

我能够通过notepad++将这两种情况下的编码转换为UTF-16LE,并使用makro成功导入文件,但我需要从我的应用程序以正确的格式创建文件

较旧的设备有android版本5.1

较新的设备有android版本9.0

这是我的密码:

File file = new File("some_name");
if (file.exists()) {
    file.delete();
}
file.getParentFile().mkdirs();
file.createNewFile();

Writer osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-16LE"); //Or "UTF-16"
osw.write("foo");
osw.write("bar");
osw.close();
如何在新设备上使用UTF-16LE编码


我确实查看了Answare,并按如下方式实现了它:

Writer osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-16LE"); //Or "UTF-16"
osw.write(new String(("foo").getBytes("UTF-16LE"), "UTF-16LE"));
osw.write(new String(("bar").getBytes("UTF-16LE"), "UTF-16LE"));
osw.close();
PS C:\> format-hex some_name.csv

           Path: C:\some_name.csv

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   FF FE 48 00 65 00 61 00 64 00 65 00 72 00 31 00  .þH.e.a.d.e.r.1.
00000010   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 32 00  ,.H.e.a.d.e.r.2.
00000020   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 33 00  ,.H.e.a.d.e.r.3.
00000030   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 34 00  ,.H.e.a.d.e.r.4.
00000040   0A 00 74 00 65 00 78 00 74 00 31 00 2C 00 74 00  ..t.e.x.t.1.,.t.
00000050   65 00 78 00 74 00 32 00 2C 00 74 00 65 00 78 00  e.x.t.2.,.t.e.x.
00000060   74 00 33 00 2C 00 74 00 65 00 78 00 74 00 34 00  t.3.,.t.e.x.t.4.
00000070   0A 00 74 00 65 00 78 00 74 00 35 00 2C 00 74 00  ..t.e.x.t.5.,.t.
00000080   65 00 78 00 74 00 36 00 2C 00 74 00 65 00 78 00  e.x.t.6.,.t.e.x.
00000090   74 00 37 00 2C 00 74 00 65 00 78 00 74 00 38 00  t.7.,.t.e.x.t.8.

我还使用了
标准字符集.UTF_16LE
,但它没有改变任何东西。记事本++仍然无法识别编码,makro也无法导入编码。

您可以尝试使用指定编码的字节顺序标记(bom)显式强制UTF-16LE编码。记事本++和Excel可以解释bom表。例如,以下代码将生成适合使用字节顺序标记导入Excel的csv文件:

public void writeFile(Context context) throws IOException {
    File file = new File(context.getFilesDir(), "some_name.csv");
    if (file.exists()) file.delete();

    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_16LE);

    // The byte order mark for UTF-16 is "\ufeff" but will appear as "\ufffe" when
    // the file is UTF-16LE.
    osw.write("\ufeff");
    osw.write("Header1,Header2,Header3,Header4\n");
    osw.write("text1,text2,text3,text4\n");
    osw.write("text5,text6,text7,text8");
    osw.close();
}
在Android 9仿真器上生成的结果文件如下所示:

Writer osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-16LE"); //Or "UTF-16"
osw.write(new String(("foo").getBytes("UTF-16LE"), "UTF-16LE"));
osw.write(new String(("bar").getBytes("UTF-16LE"), "UTF-16LE"));
osw.close();
PS C:\> format-hex some_name.csv

           Path: C:\some_name.csv

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   FF FE 48 00 65 00 61 00 64 00 65 00 72 00 31 00  .þH.e.a.d.e.r.1.
00000010   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 32 00  ,.H.e.a.d.e.r.2.
00000020   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 33 00  ,.H.e.a.d.e.r.3.
00000030   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 34 00  ,.H.e.a.d.e.r.4.
00000040   0A 00 74 00 65 00 78 00 74 00 31 00 2C 00 74 00  ..t.e.x.t.1.,.t.
00000050   65 00 78 00 74 00 32 00 2C 00 74 00 65 00 78 00  e.x.t.2.,.t.e.x.
00000060   74 00 33 00 2C 00 74 00 65 00 78 00 74 00 34 00  t.3.,.t.e.x.t.4.
00000070   0A 00 74 00 65 00 78 00 74 00 35 00 2C 00 74 00  ..t.e.x.t.5.,.t.
00000080   65 00 78 00 74 00 36 00 2C 00 74 00 65 00 78 00  e.x.t.6.,.t.e.x.
00000090   74 00 37 00 2C 00 74 00 65 00 78 00 74 00 38 00  t.7.,.t.e.x.t.8.
Notepad++对文件的解释如下:

Writer osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-16LE"); //Or "UTF-16"
osw.write(new String(("foo").getBytes("UTF-16LE"), "UTF-16LE"));
osw.write(new String(("bar").getBytes("UTF-16LE"), "UTF-16LE"));
osw.close();
PS C:\> format-hex some_name.csv

           Path: C:\some_name.csv

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   FF FE 48 00 65 00 61 00 64 00 65 00 72 00 31 00  .þH.e.a.d.e.r.1.
00000010   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 32 00  ,.H.e.a.d.e.r.2.
00000020   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 33 00  ,.H.e.a.d.e.r.3.
00000030   2C 00 48 00 65 00 61 00 64 00 65 00 72 00 34 00  ,.H.e.a.d.e.r.4.
00000040   0A 00 74 00 65 00 78 00 74 00 31 00 2C 00 74 00  ..t.e.x.t.1.,.t.
00000050   65 00 78 00 74 00 32 00 2C 00 74 00 65 00 78 00  e.x.t.2.,.t.e.x.
00000060   74 00 33 00 2C 00 74 00 65 00 78 00 74 00 34 00  t.3.,.t.e.x.t.4.
00000070   0A 00 74 00 65 00 78 00 74 00 35 00 2C 00 74 00  ..t.e.x.t.5.,.t.
00000080   65 00 78 00 74 00 36 00 2C 00 74 00 65 00 78 00  e.x.t.6.,.t.e.x.
00000090   74 00 37 00 2C 00 74 00 65 00 78 00 74 00 38 00  t.7.,.t.e.x.t.8.

导入文件后,Excel将显示以下内容:

这不会直接回答您的问题,但您应该能够将此代码与数据一起使用,以帮助诊断问题


我在评论中留下了这一点,但我将在这里再次提及:UTF解码器的行为确实随着Android 9的出现而发生了变化,从而更加符合Unicode标准。对这些变化进行了描述。不确定这对您的情况会有什么影响(如果有),但值得一看(IMO)。

您是否看到:,即确保您正在编写UTF16-LE字符串,而不是作为字符串提供编码。建议使用
标准字符集。UTF_16LE
@MorrisonChang我尝试了这两种建议,遗憾的是,这没有改变任何事情:/我已经更新了我的问题。运行Android 9.0版的较新设备是什么?Android 9中的UTF解码器行为发生了变化(请参阅)。创建CSV文件的数据源是什么?我已经尝试通过手动将BOM添加到文件来强制编码。虽然我使用了StandardCharset.UTFle,但输出仍然被识别为UTF-8,但这次使用的是BOM(UTF-8-BOM)。但令人惊讶的是,makro能够读取文件。也许makro不需要UTF-16LE,但需要一些带BOM的格式。你没有严格地回答这个问题,但帮助我解决了根本问题。我会接受这个安萨雷并以赏金奖励你。非常感谢你!!