Java 在Blackberry中上载UTF-8文本文件

Java 在Blackberry中上载UTF-8文本文件,java,file,blackberry,utf-8,ascii,Java,File,Blackberry,Utf 8,Ascii,我试图上传一个UTF-8文本文件到黑莓的服务器上。上传效果很好,但是当我在服务器中检查文件时,它是一个ASCII文件,我需要的是一个UTF-8文件 这是我创建文件时使用的代码: FileConnection fc = (FileConnection)Connector.open(fileName); if (!fc.exists()){ fc.create(); } long byteOffset = fc.usedSize(); OutputStream outStream = fc.

我试图上传一个UTF-8文本文件到黑莓的服务器上。上传效果很好,但是当我在服务器中检查文件时,它是一个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属性中有问题,但我不知道是什么问题


感谢您的帮助

查看此代码,它出现两次:

while( ( ch = in.read() ) != -1 ){
    stringBuffer.append( (char)ch );
}
在ISO-8859-1中,将每个字节视为一个单独的字符

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

这也于事无补:

byte [] _postData = postData.getBytes();
这将使用平台默认编码将字符串转换为字节——这几乎不是您想要的

鉴于您的
getData
方法试图以字节数组的形式读取文件,我认为您根本不应该将其转换为文本。如果您事先知道文件长度,您应该创建一个大小合适的字节数组,并反复调用
InputStream.read(byte[],int,int)
,记下返回值以查看读取的距离。如果不这样做,您可以重复读取一个较小的缓冲区,然后将刚刚读取的数据写入一个
ByteArrayOutputStream
,稍后可以从中获取字节数组


此外,您似乎从来没有关闭过任何流—您应该在
finally
语句中这样做,这样即使引发异常,流也会关闭。

请查看出现两次的代码:

while( ( ch = in.read() ) != -1 ){
    stringBuffer.append( (char)ch );
}
在ISO-8859-1中,将每个字节视为一个单独的字符

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

这也于事无补:

byte [] _postData = postData.getBytes();
这将使用平台默认编码将字符串转换为字节——这几乎不是您想要的

鉴于您的
getData
方法试图以字节数组的形式读取文件,我认为您根本不应该将其转换为文本。如果您事先知道文件长度,您应该创建一个大小合适的字节数组,并反复调用
InputStream.read(byte[],int,int)
,记下返回值以查看读取的距离。如果不这样做,您可以重复读取一个较小的缓冲区,然后将刚刚读取的数据写入一个
ByteArrayOutputStream
,稍后可以从中获取字节数组


此外,您似乎从来没有关闭过任何流—您应该在
finally
语句中这样做,这样即使抛出异常,流也会关闭。

除了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);

除了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);


+1但ISO-8859-1中没有漏洞,
0x80-0x9F
范围映射到相同unicode代码点值的C1控制字符。@Esailija:将删除该位。我原以为这是一个实际的漏洞,但我相信这在您阅读的文档中有所不同:(根据维基百科的说法,有漏洞的是
ISO 8859-1
(无破折号),补充了C0和C1的是
ISO-8859-1
(ISO后面的破折号):P@Esailija:啊,这几乎肯定就是我困惑的地方。(坦白地说,我没有把太多的责任归咎于这一点!)@Jon Skeet:+1。我刚刚发布了一个更简单的方法,可以从BlackBerry上的文件中读取字节。+1但是ISO-8859-1中没有漏洞,
0x80-0x9F
范围映射到相同unicode代码点值的C1控制字符。@esailja:将删除该位。我原以为这是一个实际的漏洞,但我相信不同的文档会有不同的漏洞ead:(根据维基百科,有孔的是
ISO 8859-1
(无破折号),补充了C0和C1的是
ISO-8859-1
(ISO后面的破折号):P@Esailija:啊。几乎可以肯定,这就是我困惑的地方。(坦白说,我不会把太多的责任归咎于这件事!)@Jon Skeet:+1.我刚刚发布了一个更简单的方法,可以在BlackBerry上读取文件中的字节。感谢Arhimed,我尝试了IOUtilities.streamToBytes(),但文件仍然以ASCII格式上载到服务器中。如果使用
String.getBytes(“UTF-8”)将数据保存到文件中
,则数据的编码正确。如果以后在设备端仅将该数据作为字节数组进行操作,则编码不会更改,服务器应以正确的编码对其进行处理。这可能是服务器端的问题-您确定服务器正确处理获取的二进制数据吗?已解决。问题是:我正在使用包含只有ASCII字符,这就是为什么当我在服务器端使用
file-ib
命令时,我总是收到
charset:us ASCII
之后,我尝试在文件中使用特殊字符,命令结果是
charset:utf-8
。顺便说一句,我将您的答案标记为正确,因为我获取字节数组的方式是错了,你的答案是对的。谢谢Arhimed。事实上,Jon Skeet的答案值得解答mark,因为他是第一个向你解释错误的人。而我的答案只是展示了一种简单的方法来实现他的建议。所以请随意将解答转移到他的答案上。+1,因为我认为
IOUtilities.streamToBytes()
确实是最好的解决方案,对于BlackBerry Java…以及良好的体育精神:)谢谢Arhimed,我已经尝试了IOUtilities.streamToBytes(),但文件仍然以ASCII格式上载到服务器中。如果您使用
Strin将数据保存到文件中