在Java中写入ASCII 0-255的数据类型(ServletOutputStream)

在Java中写入ASCII 0-255的数据类型(ServletOutputStream),java,servlets,character-encoding,bytearray,outputstream,Java,Servlets,Character Encoding,Bytearray,Outputstream,我有一个数组“result”,它包含0-255之间的值。我最初将其声明为byte[],但当我必须写入128时,结果[I]得到值-128,并在输出文件中写入“€”,最终读取为8364 正如我所看到的,字节只接受值-128到127,对于0-255之间的值,我应该使用什么数据类型(不浪费内存) 我应该同时更改内容类型还是添加任何字符集标题 谢谢 res.setContentType("application/octet-stream"); res.setHeader("Content-Disposi

我有一个数组“result”,它包含0-255之间的值。我最初将其声明为byte[],但当我必须写入128时,结果[I]得到值-128,并在输出文件中写入“€”,最终读取为8364

正如我所看到的,字节只接受值-128到127,对于0-255之间的值,我应该使用什么数据类型(不浪费内存)

我应该同时更改内容类型还是添加任何字符集标题

谢谢

res.setContentType("application/octet-stream"); 
res.setHeader("Content-Disposition","attachment;filename=output.js");
ServletOutputStream os = res.getOutputStream();
byte[] result=encode(req.getParameter("originalScript")); // Result[i]=-128 (should be 128)
os.write(result,0,result.length); // result[i] on output.js is written as "€" (8364)

很难相信您的应用程序在这个时代有如此严格的内存要求

不必进一步质疑你的动机,以下是你可以做的:

byte[] result=encode(req.getParameter("originalScript"));
char[] tmp = new char[result.length];
for (int i = 0 ; i != result.length ; i++) {
    tmp[i] = (char)(result[i] & 0xFF);
}
os.print(new String(tmp));

你被几个概念混在一起弄糊涂了

首先,int 128与字节-128相同(int 255==字节-1,254==-2,…128=-128)。字节是有符号的,符号信息位于最高位。您的错误在于没有使用正确的方法将字节值转换回int。要解决此问题,请使用以下代码:

b = (byte) 128;
int i = b & 0xff;
System.out.println(b);
System.out.println(i);
给出
-128
128

下一步:ASCII仅为0和127之间的值定义。这意味着任何大于127的东西都是垃圾,除非你仔细对待它

问题是当您读取代码的输出时。由于ASCII不能包含大于127的值,读取代码应该做什么

“output.js”听起来像是在使用web浏览器将此数据作为JavaScript文件读取。web浏览器将尝试使用“编码”将字节流转换为文本。如果不指定一个,浏览器必须猜测错误(而且
application/octet-stream
似乎也错了。这不应该是
text/javascript
?)

您有两个选择:

  • 更改
    encode()

  • 将字符集设置为
    ISO-8859-1
    ,这将保留字节1:1。如果脚本包含任何大于255的Unicode字符,则此操作将失败。因为不会出现错误,所以不应该使用这种方法。我只是为了完整起见才提到它

  • response.setHeader("Content-Type", "text/javascript; charset=UTF-8");