【问题标题】:Uploading an UTF-8 text file in Blackberry在 Blackberry 中上传 UTF-8 文本文件
【发布时间】:2013-01-03 15:13:42
【问题描述】:

我正在尝试将 UTF-8 文本文件上传到 Blackberry 中的服务器。上传效果很好,但是当我检查服务器中的文件时,它是一个 ASCII 文件,我需要的是一个 UTF-8 文件。

这是我创建文件时使用的代码:

FileConnection fc = (FileConnection)Connector.open(fileName);
if (!fc.exists()){
    fc.create();
}
long byteOffset = fc.usedSize();
OutputStream outStream = fc.openOutputStream(byteOffset);           
outStream.write(line.getBytes("UTF-8"));
outStream.close();
fc.close();

要发送文件,我使用这个:

public void run (){

    httpConnection = null;
    _connectionURL = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--"; 
    String boundary = "*****";  
    int rc = -1;
    OutputStream os = null;

    try {

        _connectionURL = Constants.UPLOAD_URL + getConnectionString();

        httpConnection = (HttpConnection)Connector.open(_connectionURL);
        byte [] postDataBytes = getData();

        httpConnection.setRequestMethod("POST");
        httpConnection.setRequestProperty("Connection", "Keep-Alive"); 
        httpConnection.setRequestProperty("User-Agent", "BlackBerry");
        httpConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=*****");                        
        httpConnection.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LANGUAGE, "en-US");
        httpConnection.setRequestProperty(HttpProtocolConstants.HEADER_CACHE_CONTROL,"no-cache, no-store, no-transform");           

        os = httpConnection.openOutputStream();
        os.write((twoHyphens + boundary + lineEnd).getBytes());
        os.write(("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + fileName +"\"" + lineEnd).getBytes());
        os.write(lineEnd.getBytes());
        os.write(postDataBytes);
        os.write(lineEnd.getBytes());
        os.write((twoHyphens + boundary + twoHyphens + lineEnd).getBytes());
        os.flush(); 


        // Response
        rc = httpConnection.getResponseCode();
        InputStream in = httpConnection.openInputStream();
        int ch;
        StringBuffer stringBuffer = new StringBuffer();
        while( ( ch = in.read() ) != -1 ){
            stringBuffer.append( (char)ch );
        }            
        String responseString = stringBuffer.toString();

        ...

    }catch (IOException ioe){
       ...
    }
}

...

private byte[] getData() throws IOException {
    int _c;
    StringBuffer _stringBuffer = new StringBuffer("UTF-8");
    FileConnection fileForUpload = (FileConnection) Connector.open(Constants.FOLDER_FILES+this.fileName, Connector.READ);
    this.fileInputStream = fileForUpload.openDataInputStream();
    this.postData = new URLEncodedPostData("UTF-8", false);
    while( (_c = this.fileInputStream.read()) != -1){
        _stringBuffer.append((char)_c);         
    }
    postData.setData(_stringBuffer);
    byte [] _postData = postData.getBytes();
    fileForUpload.close();
    return _postData;
}

我猜 getData() 方法或 httpConnection 属性有问题,但我不知道是什么问题。

感谢您的帮助

【问题讨论】:

    标签: java file blackberry utf-8 ascii


    【解决方案1】:

    除了 Jon Skeet 的回答。

    要从文件中读取字节数组,您可以简单地使用net.rim.device.api.io.IOUtilities:

    FileConnection fileForUpload = 
            (FileConnection) Connector.open(path, Connector.READ);
    InputStream stream = fileForUpload.openInputStream();
    byte[] data = IOUtilities.streamToBytes(stream);
    

    【讨论】:

    • 感谢 Arhimed,我已尝试使用 IOUtilities.streamToBytes(),但文件仍以 ASCII 格式上传到服务器中。
    • 好吧,如果您使用String.getBytes("UTF-8") 将数据保存到文件中,那么数据的编码正确。如果稍后在设备端您仅将该数据作为字节数组进行操作,则编码不会改变,服务器应该以正确的编码获取它。这可能是服务器端问题 - 您确定服务器正确处理获取的二进制数据吗?
    • 已解决。问题是:我正在使用仅包含 ASCII 字符的文件进行测试,这就是为什么当我在服务器端使用 file -ib 命令时,我总是收到 charset: us-ascii 之后,我尝试在文件和命令中使用特殊字符结果是charset: utf-8。顺便说一句,我将您的答案标记为正确,因为我获取字节数组的方式是错误的,而您的答案是正确的。谢谢你,Arhimed。
    • 好吧,实际上 Jon Skeet 的回答值得解决,因为他是第一个向您解释问题所在的人。而我的只是展示了一种简单的方法来做他建议的事情。因此,请随意将解决方案移至他的答案。
    • +1,因为我认为 IOUtilities.streamToBytes() 确实是最好的解决方案,对于 BlackBerry Java ...以及良好的体育精神 :)
    【解决方案2】:

    看看这段代码,它出现了两次:

    while( ( ch = in.read() ) != -1 ){
        stringBuffer.append( (char)ch );
    }
    

    这将每个字节视为一个单独的字符,在 ISO-8859-1 中有效。

    如果您真的想将内容转换为文本,您应该使用编码为 UTF-8 的 InputStreamReader,然后理想地读取 个字符(而不是一个字符时间)。

    这也无济于事:

    byte [] _postData = postData.getBytes();
    

    这将使用平台默认编码将字符串转换为字节 - 这几乎是从不你想要的。

    鉴于您的 getData 方法正在尝试将文件读取为字节数组,您根本不应该将其转换为文本,IMO。如果您事先知道文件长度,您应该只创建一个大小合适的字节数组并重复调用InputStream.read(byte[], int, int),注意返回值以查看您已阅读多远。如果不这样做,您可以反复读入一个较小的缓冲区,然后将刚刚读入的数据写入ByteArrayOutputStream,以后可以从中获取字节数组。

    此外,您似乎从未关闭任何流 - 您应该在 finally 语句中执行此操作,以便即使引发异常也关闭流。

    【讨论】:

    • +1 但 ISO-8859-1 没有漏洞,0x80-0x9F 范围映射到相同 unicode 码位值的 C1 控制字符。
    • @Esailija:将删除该位。我认为这是一个实际的漏洞,但我相信您阅读的文件会有所不同:(
    • 好吧,根据维基百科,有孔的是ISO 8859-1(没有破折号),补充有C0和C1的是ISO-8859-1(ISO之后的破折号):P
    • @Esailija:啊。这几乎肯定是我感到困惑的地方。 (坦率地说,我并没有在这件事上过分责备自己!)
    • @Jon Skeet:+1。我刚刚发布了一种从 BlackBerry 上的文件中读取字节的更简单方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    相关资源
    最近更新 更多