Java文件编码魔术

时间:2015-03-24 08:07:04

标签: java endianness byte-order-mark

奇怪的事情发生在爪哇王国...... 简而言之:我使用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来运行代码

1 个答案:

答案 0 :(得分:2)

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

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