【问题标题】:Java file encoding magicJava文件编码魔术
【发布时间】:2015-05-27 11:12:33
【问题描述】:

Java王国发生了奇怪的事情...
长话短说:我使用 Java API V3 连接到 QuickBooks 并在那里获取数据表单(例如服务)。
除了服务包含俄语符号(或可能是非拉丁符号)的情况外,一切都很好。
这是执行此操作的 Java 代码(我知道它远非完美)

package com.mde.test;

import static com.intuit.ipp.query.GenerateQuery.$;
import static com.intuit.ipp.query.GenerateQuery.select;
import java.util.LinkedList;
import java.util.List;

import com.intuit.ipp.core.Context;
import com.intuit.ipp.core.ServiceType;
import com.intuit.ipp.data.Item;
import com.intuit.ipp.exception.FMSException;
import com.intuit.ipp.query.GenerateQuery;
import com.intuit.ipp.security.OAuthAuthorizer;
import com.intuit.ipp.services.DataService;
import com.intuit.ipp.util.Config;

public class TestEncoding {

    public static final String QBO_BASE_URL_SANDBOX = "https://sandbox-quickbooks.api.intuit.com/v3/company";

    private static String consumerKey = "consumerkeycode"; 
    private static String consumerSecret = "consumersecretcode"; 
    private static String accessToken = "accesstokencode"; 
    private static String accessTokenSecret = "accesstokensecretcode"; 
    private static String appToken = "apptokencode"; 
    private static String companyId = "companyidcode";

    private static OAuthAuthorizer oauth = new OAuthAuthorizer(consumerKey, consumerSecret, accessToken, accessTokenSecret);

    private static final int PAGING_STEP = 500;


    public static void main(String[] args) throws FMSException {
        List<Item> res = findAllServices(getDataService());
        System.out.println(res.get(1).getName());
    }

    public static List<Item> findAllServices(DataService service) throws FMSException {
        Item item = GenerateQuery.createQueryEntity(Item.class);
        List<Item> res = new LinkedList<>();

        for (int skip = 0; ; skip += PAGING_STEP) {
            String query = select($(item)).skip(skip).take(PAGING_STEP).generate();
            List<Item> items = (List<Item>)service.executeQuery(query).getEntities();
            if (items.size() > 0)
                res.addAll(items);
            else
                break;
        }
        System.out.println("All services fetched");
        return res;
    }

    public static DataService getDataService() throws FMSException {
        Context context = getContext();
        if (context == null) {
            System.out.println("Context is null,  something wrong, dataService also will null.");
            return null;
        }
        return getDataService(context);
    }

    private static Context getContext() {
        try {
            return new Context(oauth, appToken, ServiceType.QBO, companyId);
        } catch (FMSException e) {
            System.out.println("Context is not loaded");
            return null;
        }
    }

    protected static DataService getDataService(Context context) throws FMSException {
        DataService service = new DataService(context);
        Config.setProperty(Config.BASE_URL_QBO, QBO_BASE_URL_SANDBOX);
        return new DataService(context);
    }
    }

此文件以 UTF-8 格式保存。它打印出类似

获取所有服务
Сэрвыс, РѕС,РЅСЋРґСЊ

但是!当我用 BOM 将这个文件保存为 UTF-8 时......我得到了正确的数据!

获取所有服务
Сэрвыс, отнюдь

有人可以解释发生了什么吗? :)
// 我使用 Eclipse 运行代码

【问题讨论】:

    标签: java endianness byte-order-mark


    【解决方案1】:

    您正在从与您共享不同字节顺序的系统中获取数据,因此当您使用 BOM 保存文件时,它会在文件中添加足够的信息,以便将来的程序会按照远程系统的字节顺序读取它.

    当您在没有 BOM 的情况下保存它时,它以远程系统的字节顺序写入文件,而没有任何存储字节顺序的指示,因此当您读取它时,您使用本地系统的(不同的)字节顺序读取它。这会混淆多字节字符中的字节,使输出看起来毫无意义。

    【讨论】:

    • 这听起来对我来说不是那么简单:) 我没有得到“远程系统字节排序”的想法,仍然不明白 java 文件编码如何影响 DATA 编码。编译器根据 .java 文件的编码产生不同的 .class 文件?我不争辩,我相信这是一个正确的答案,但您能否提供任何链接或“进一步阅读”以了解此过程的具体运作方式? :) 或者别的 :)
    • @Zmiter 这样想。如果你在一页纸上画一幅画,那么在你把那张纸储存起来并取回它之后,它看起来仍然是同一张画。如果由于图片很大而必须使用两张纸,那么存储它的人和检索它的人必须协调,否则您就有可能因为页面颠倒而得到不同的图片。在 UTF-8 中,大多数字符需要一个以上的字节,并且您以与存储顺序不同的顺序检索它。 BOM 就像一张便条,说明检索字节的顺序。
    • 这很清楚 :) 但在我的情况下 .java 文件对应于您描述的图片,因为 BOM 直接说明以什么顺序检索该文件的字节,所以为什么它会影响 DATA来自服务(数据是另一张图片)? /* 看起来如果第一个开发人员构建代码,它会正常工作,如果第二个开发人员只使用另一种编码构建代码,它会失败,对吧? */
    • @Zmiter 所以 Java 文件通常是 UTF-8。这是一种编码,它将恰好对应于 ASCII 字符的所有字节存储为一个字节(因此它们不会被翻转)并将所有非 ASCII 字符存储为一个以上的字节(因此它们将被翻转)。我希望这可以解释为什么像“while (”这样的字节不会被弄乱(不能翻页图纸)但是像 Cryllic 这样的字节会被弄乱,除非你还包括 BOM。
    • 我的观点一定是解释错了:) 这就是我的意思gyazo.com/f0180faf72ba88e4607b71313464c9c8
    猜你喜欢
    • 2011-07-06
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 2013-01-23
    • 1970-01-01
    • 2012-05-20
    相关资源
    最近更新 更多