【问题标题】:Issue uploading by ftp file通过 ftp 文件上传问题
【发布时间】:2014-12-25 19:43:35
【问题描述】:

我在通过 FTP 上传文件到我的服务器时遇到问题。该文件是一个json文件,我读得很好,没有符号。这是我上传文件的代码:

   public static void subir(){
        String server = server;
        int port = 21;
        String user = user;
        String pass = pass;

        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");

        try {

            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
            ftpClient.enterLocalPassiveMode();

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            // Uploads first file using an InputStream
            File firstLocalFile = new File("my.json");

            String firstRemoteFile = "Folder/my.json";
            InputStream inputStream = new FileInputStream(firstLocalFile);

            System.out.println("Subiendo archivo a servidor...");
            boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
            inputStream.close();
            if (done) {
                System.out.println("great");
            }


        } catch (IOException ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

问题是,当我打开包含我的文件的 url 时,我用符号读取了我的信息,例如 parecÃa 而不是 parecía,Giménez 而不是 Giménez。有人可以帮助我吗?谢谢

我手动创建我的 json:

sBuffer = new StringBuffer();
         a= "{\"results\":[";
         sBuffer.append(a);

        for (int z=0; z< myarray.size(); z++){
          if (z<(myarray.size()-1)){
              b="{\"one\":\""+ myarray.get(z).getOne()+"\",\"twoo\":\""+ myarray.get(z). getTwoo()+"\",\"three\":\""+ myarray.get(z).getThree()+"\"},";
              sBuffer.append(b);
          }
          else{
              c="{\"one\":\""+ myarray.get(z). getOne()+"\",\"twoo\":\""+ myarray.get(z).getTwoo()+"\",\"three\":\""+myarray.get(z). getThree()+"\"}]}";
              sBuffer.append(c);
          }

        }

【问题讨论】:

  • 您使用的 URL 应该发送一个 Content-type 标头,指示 UTF-8。
  • 我不明白,举个例子?谢谢
  • 在我的服务器中的其他 json 中,我没有任何内容类型,问题是通过 ftp 上传
  • 你说你访问了一个 URL。这可能意味着来自网络服务器的http:... URL。现在,如果它没有在其Content-type 标头中发送正确的字符编码,您将得到一个乱码文件(假设您的文件确实是UTF-8)。因此,您必须更改您在服务器端使用的任何内容(一个 servlet?一个 PHP 脚本?什么程序返回您的文件?),以便它在该标头中设置正确的字符编码。
  • 问题可能不是通过 FTP 上传,而是其他 JSON 可能使用\uXXXX 符号对字符进行编码,因此它们没有编码问题。

标签: java utf-8 ftp


【解决方案1】:

总结一下我的cmets:

包含不在 ASCII 范围内的字符(如 éñ)的 JSON 文件可以通过两种方式表示:

  1. 纯 ASCII 文件。所有“特殊”字符都由 unicode 转义序列表示。例如,é 将表示为 \u00E9ñ\u00F1。文件中的数据实际上是字符\,u,0,0,F,1,但是任何好的 JSON 解释器都会读取它并在内部将其转换为正确的字符。

  2. 编码文件。根据您保存它们的特定编码,“特殊”字符由 8 位字节表示。如果您选择 UTF-8,则文件中为 é 保存的实际字节为 0xC3 0xC9。对于ñ,字节为0xC30xB1。这就是 UTF-8 编码的工作原理 - 每个“特殊”字符由两个或多个 8 位字节表示。

现在您已经创建了一个 UTF-8 文件并将其放在您的服务器上成功。它是成功的,因为您使用 binary 传输方法,这意味着它不进行任何编码,而只是将字节原样传递给服务器。

问题在于你如何读回数据。

每个 HTTP URL 在响应请求时都会发送一个标头,告诉浏览器或读取它的程序返回什么类型的响应,以及字符的编码是什么

例如,如果 URL 发送标头:

内容类型:text/html; charset="ISO-8859-1"

然后浏览器或阅读程序知道 (a) 这个文件包含文本数据,采用 HTML 格式,并且 (b) 它的字符编码是ISO-8859-1

如果 URL 发送标头:

内容类型:文本/纯文本; charset="UTF-8"

那么浏览器或阅读程序就知道(a)这个文件包含没有特定格式的文本,并且(b)它的字符编码是UTF-8

您的问题是 URL 提供了一个以 UTF-8 编码的文件。但它的标题说内容类型是ISO-8859-1

这意味着当浏览器看到浏览器发送的字节序列C3A9,应该是é,它会根据ISO-8859-1编码来解释它们。在该编码中,每个字节都是一个单独的字符。 C3 实际上是ISO-8859-1 中的Ã,而A9©。所以你在浏览器中看到的是é,而不是é。发送的数据是相同的字节序列。该文件未更改。但是由于标题,您的浏览器/阅读器在内部对其进行了转换并将其显示为不同的字符。

你是怎么解决这个问题的?

  1. 创建文件时,请使用转义序列\uXXXX 创建它。无论 HTTP 响应的编码是 US-ASCII、任何 ISO-8859 编码还是 UTF-8,这都会起作用。

  2. URL 由某种网络程序操作:servlet、PHP 脚本或其他东西。该程序应该发送正确的Content-type 标头,当然不是ISO-8859-1 之类的东西。 JSON 的正确内容类型应为 application/json。如果它发送它,则不需要设置字符集,因为您只对text/* 编码执行此操作,而不是对被视为字节流的application/* 执行此操作。像 Firefox 这样的普通浏览器可能理解也可能不理解,但是应该读取 JSON URL 的程序应该理解这一点,并自动将 JSON 数据解释为 UTF-8。但如果这不起作用(因为您实际上是在使用一些文本工具或 Internet Explorer 查看数据,而不是特定于 JSON 的东西),您可以将标头设置为 text/plain; charset="UTF-8"text/javascript; charset="UTF-8"

    请注意,如果您访问的是直接 URL,例如 http://server/folder/file.json,则意味着 Web 服务器(apache、IIS 等)正在根据其对 .json 后缀的配置设置来设置标头。在这种情况下,您必须更改该后缀的服务器配置。


要在创建 JSON 文件时以编程方式将字符串转换为转义格式,您可以执行以下操作之一(按从最佳到最差的顺序):

  • 使用适当的 JSON 库来创建 JSON。
  • 使用适当的字符串操作库来取消转义字符串。例如,Apache Commons StringEscapeUtils
  • 使用诸如此类的方法将字符串的字符附加到您的StringBuffer

    private static void appendEscaped( StringBuffer sBuffer, String str) {
        char [] strChars = str.toCharArray();
        for ( char c : strChars ) {
            if ( c >= ' ' && c <= '~' && c != '/') {
                // Character is ASCII, append as is
                sBuffer.append(c);
            } else {
                sBuffer.append(String.format("\\u%04x", (int)c));
            }
        }
    }
    

【讨论】:

  • 谢谢,但我无法使用转义序列创建 JSON,因为 Json 会以编程方式更改。第二种可能性,我必须把这个标题放在哪里?在我的 Json 文件中?
  • 好吧,您可以以编程方式使用转义序列创建它。至于第二种可能,你访问的URL后面的程序是什么?
  • 我怎样才能创建这个转义序列?我没有访问任何程序,我在 safari 中看到了我的 json
  • myserver.com/Folder/example.json 这样我看到了我的json
  • 因此您需要更改以.json 结尾的文件的服务器配置。如何做到这一点取决于特定的服务器,我假设你可以控制它的配置。为了帮助您处理转义字符,我需要您将用于创建 json 的代码、您使用的库等添加到您的问题中。
猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2013-03-24
  • 2018-01-05
  • 2012-02-22
  • 1970-01-01
相关资源
最近更新 更多