无语了,输出的全是Char码值

timi先生
新星创作者: 编程框架技术领域
2020-08-16 08:48:46

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/*
数量最大的字节
*/

public class Solution {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String filename = reader.readLine();
FileInputStream inputStream = new FileInputStream(filename);
ArrayList<Integer> list = new ArrayList<>();
HashMap<Integer,Integer>map = new HashMap<>();
long sum = 0;
long max = 0;
int a = 0;
while (inputStream.available() > 0) {
int data = inputStream.read();
list.add(data);

}
inputStream.close();
for (int i = 0; i < list.size(); i++) {
if(max<sum) {
max = sum;
sum = 0;
}
for (int j = 0; j < list.size(); j++) {
if (list.get(j).equals(list.get(i))) {
sum++;
map.put(list.get(i), Math.toIntExact(sum));
}
}
}
for (Map.Entry<Integer,Integer>pair : map.entrySet()){
Integer value = pair.getValue();
Integer key = pair.getKey();
System.out.println(key+":"+value);

}

}
}


如上所示是我的代码,读取文件是一个纯数字的TXT格式文件。读出来的数字全是char码值,没一个正常的。到底是哪里出了问题,还是FileInputStream读出来的就是char的!!!
...全文
8009 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
小灰狼 2020-08-19
  • 打赏
  • 举报
回复
引用 8 楼 qybao 的回复:
[quote=引用 7 楼 小灰狼 的回复:] 你不能考虑读一个字符的情况吧 用UTF8或GBK时,确实按次序读出来的 但是如果是一串英文数字字符,比如“1234567”,Unicode 编码就是 0x31, 0x00, 0x31, 0x00…… 每个ASCII字符后面会补一个 0x00占位。这时程序就要考虑怎么过滤掉这些占位的空白字符。 另外,如果我没记错的话,在windows下,unicode的文本文件会加两个字节的前缀,用来标记这是一个unicode文件
这补0跟它的值是不是ascii码有关系吗?(我上面也说了,不管你是在高位补0,还是低位补0) 0x31不还是‘1’的ascii码吗?你能因为它是不同的编码而改变他的值吗(我还以为你能神奇到用不同的编码能把它的值读出来不是0x31,比如读出来值是0x91之类的)? 编码只是改变字符的字节占用大小,但不影响单字节字符的ascii码(大不了就是高位补0或地位补0而已),明白吗? 按你的思路,是不是LZ换一种编码结果就能解决问题了?所以不要动不动就说什么编码问题。 unicode文件开头两个字节为0xFFFE或0xFEFF(高位模式),一般用于判断文件是什么编码。这不是windows特有,其他系统也一样。 [/quote] 您老人家怎么就越扯越远了 我想说的是,楼主一个字节一个字节地读文件,如果遇到象utf8这样的变长编码,中间就会读到非 ascii 数据,比如会读到 0x00、0xFF,这时楼主就不能简单地把每个读到的字节当作ASCII处理,必须要有过滤。
qybao 2020-08-18
  • 打赏
  • 举报
回复
引用 5 楼 小灰狼 的回复:
UTF8是变长,在表示ASCII字符时确实是一个字节
GBK也可以认为是变长,在ASCII字符表里也是一个字节
但Unicode是定长编码,所有字符都是两个字节,不信你自己试一下,一段全ASCII字符的文本文件,保存为Unicode编码时,文件大小是保存为ANSI的两倍


编码不同,字符长度不同,这个地球人都知道
但我的意思你却不明白,你用一个文本文件保存一个字符'1'或'a',你把文本文件改成各种编码保存,然后用byte的方式读出来,你去看byte的值是什么?不管你是单字节还是多字节编码,最终byte的值是不是和ascii码一样?你所谓的Unicode是定长编码,只不过是追加一个或多个byte(Unicode又分高位或低位两种方式)来补0而已,但不影响这个单字节字符的值是ascii码,正因为这样,我们才可以从ascii码判断该字符是不是'1'或'a'。

小灰狼 2020-08-18
  • 打赏
  • 举报
回复
引用 3 楼 qybao 的回复:
[quote=引用 2 楼 小灰狼 的回复:][quote=引用 1 楼 qybao 的回复:]是的,FileInputStream的read读出来的就是char,确切地说读出来的是个byte,就是读出一个字节。lz可以自己好好看看文档。 文本文件的信息是当作字符串的形式保存的,比如文本文件里的1,所以以字节的方式读出来,就是‘1’这个字符的ascii码,以字符串的形式读取出来才是“1” 如果想以字符串的形式读入信息,可以改用BufferedReader的readLine(按文本每行读入)或用Scanner的nextLine(按文本每行读入)或nextInt(按单个int类型读入),比如 BufferedReader br = new InputStreamRrader(inputStream); String s=null; while((s=br.readLine())!=null) { int data = Integer.valueOf(s); //前提是文本按int+换行的形式保存 list.add(data); } 或者 Scanner sc = new Scanner(new File(filename)); while(sc.hasNext()) { int data = sc.nextInt();//前提是文本按int+空格或换行的形式保存数据 list.add(data); }
读出来的不一定是 ASCII码,要看文本文件的编码 如果楼主的文本文件是以 utf8, unicode 或者GBK、GB2312等等编码保存,肯定不是ASCII码值[/quote]你可以试试用各种编码读出1字符,看看有什么不同?这些编码只是对于多字节字符的保存信息也许不同(比如同一个汉字,有的用两个字节保存,有的用三个字节保存),但是对于单字节字符(比如英文字母,阿拉伯数字,统一都是ascii码),我没见过对于英文字母或阿拉伯数字等单字节字符按byte读取,获得的不是ascii的情况。如果不是ascii码,你就没法判断‘a’字符是不是‘a’。所以不要什么问题都用编码来乱套。[/quote] UTF8是变长,在表示ASCII字符时确实是一个字节 GBK也可以认为是变长,在ASCII字符表里也是一个字节 但Unicode是定长编码,所有字符都是两个字节,不信你自己试一下,一段全ASCII字符的文本文件,保存为Unicode编码时,文件大小是保存为ANSI的两倍
qybao 2020-08-18
  • 打赏
  • 举报
回复
引用 7 楼 小灰狼 的回复:
你不能考虑读一个字符的情况吧
用UTF8或GBK时,确实按次序读出来的
但是如果是一串英文数字字符,比如“1234567”,Unicode 编码就是 0x31, 0x00, 0x31, 0x00…… 每个ASCII字符后面会补一个 0x00占位。这时程序就要考虑怎么过滤掉这些占位的空白字符。
另外,如果我没记错的话,在windows下,unicode的文本文件会加两个字节的前缀,用来标记这是一个unicode文件

这补0跟它的值是不是ascii码有关系吗?(我上面也说了,不管你是在高位补0,还是低位补0) 0x31不还是‘1’的ascii码吗?你能因为它是不同的编码而改变他的值吗(我还以为你能神奇到用不同的编码能把它的值读出来不是0x31,比如读出来值是0x91之类的)?
编码只是改变字符的字节占用大小,但不影响单字节字符的ascii码(大不了就是高位补0或地位补0而已),明白吗?
按你的思路,是不是LZ换一种编码结果就能解决问题了?所以不要动不动就说什么编码问题。
unicode文件开头两个字节为0xFFFE或0xFEFF(高位模式),一般用于判断文件是什么编码。这不是windows特有,其他系统也一样。

小灰狼 2020-08-18
  • 打赏
  • 举报
回复
引用 6 楼 qybao 的回复:
[quote=引用 5 楼 小灰狼 的回复:] UTF8是变长,在表示ASCII字符时确实是一个字节 GBK也可以认为是变长,在ASCII字符表里也是一个字节 但Unicode是定长编码,所有字符都是两个字节,不信你自己试一下,一段全ASCII字符的文本文件,保存为Unicode编码时,文件大小是保存为ANSI的两倍
编码不同,字符长度不同,这个地球人都知道 但我的意思你却不明白,你用一个文本文件保存一个字符'1'或'a',你把文本文件改成各种编码保存,然后用byte的方式读出来,你去看byte的值是什么?不管你是单字节还是多字节编码,最终byte的值是不是和ascii码一样?你所谓的Unicode是定长编码,只不过是追加一个或多个byte(Unicode又分高位或低位两种方式)来补0而已,但不影响这个单字节字符的值是ascii码,正因为这样,我们才可以从ascii码判断该字符是不是'1'或'a'。 [/quote] 你不能考虑读一个字符的情况吧 用UTF8或GBK时,确实按次序读出来的 但是如果是一串英文数字字符,比如“1234567”,Unicode 编码就是 0x31, 0x00, 0x31, 0x00…… 每个ASCII字符后面会补一个 0x00占位。这时程序就要考虑怎么过滤掉这些占位的空白字符。 另外,如果我没记错的话,在windows下,unicode的文本文件会加两个字节的前缀,用来标记这是一个unicode文件
苜苜的烂笔头 2020-08-17
  • 打赏
  • 举报
回复
qybao 2020-08-17
  • 打赏
  • 举报
回复
引用 2 楼 小灰狼 的回复:
[quote=引用 1 楼 qybao 的回复:]是的,FileInputStream的read读出来的就是char,确切地说读出来的是个byte,就是读出一个字节。lz可以自己好好看看文档。 文本文件的信息是当作字符串的形式保存的,比如文本文件里的1,所以以字节的方式读出来,就是‘1’这个字符的ascii码,以字符串的形式读取出来才是“1” 如果想以字符串的形式读入信息,可以改用BufferedReader的readLine(按文本每行读入)或用Scanner的nextLine(按文本每行读入)或nextInt(按单个int类型读入),比如 BufferedReader br = new InputStreamRrader(inputStream); String s=null; while((s=br.readLine())!=null) { int data = Integer.valueOf(s); //前提是文本按int+换行的形式保存 list.add(data); } 或者 Scanner sc = new Scanner(new File(filename)); while(sc.hasNext()) { int data = sc.nextInt();//前提是文本按int+空格或换行的形式保存数据 list.add(data); }
读出来的不一定是 ASCII码,要看文本文件的编码 如果楼主的文本文件是以 utf8, unicode 或者GBK、GB2312等等编码保存,肯定不是ASCII码值[/quote]你可以试试用各种编码读出1字符,看看有什么不同?这些编码只是对于多字节字符的保存信息也许不同(比如同一个汉字,有的用两个字节保存,有的用三个字节保存),但是对于单字节字符(比如英文字母,阿拉伯数字,统一都是ascii码),我没见过对于英文字母或阿拉伯数字等单字节字符按byte读取,获得的不是ascii的情况。如果不是ascii码,你就没法判断‘a’字符是不是‘a’。所以不要什么问题都用编码来乱套。
小灰狼 2020-08-17
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
是的,FileInputStream的read读出来的就是char,确切地说读出来的是个byte,就是读出一个字节。lz可以自己好好看看文档。 文本文件的信息是当作字符串的形式保存的,比如文本文件里的1,所以以字节的方式读出来,就是‘1’这个字符的ascii码,以字符串的形式读取出来才是“1” 如果想以字符串的形式读入信息,可以改用BufferedReader的readLine(按文本每行读入)或用Scanner的nextLine(按文本每行读入)或nextInt(按单个int类型读入),比如 BufferedReader br = new InputStreamRrader(inputStream); String s=null; while((s=br.readLine())!=null) { int data = Integer.valueOf(s); //前提是文本按int+换行的形式保存 list.add(data); } 或者 Scanner sc = new Scanner(new File(filename)); while(sc.hasNext()) { int data = sc.nextInt();//前提是文本按int+空格或换行的形式保存数据 list.add(data); }
读出来的不一定是 ASCII码,要看文本文件的编码 如果楼主的文本文件是以 utf8, unicode 或者GBK、GB2312等等编码保存,肯定不是ASCII码值
qybao 2020-08-17
  • 打赏
  • 举报
回复
是的,FileInputStream的read读出来的就是char,确切地说读出来的是个byte,就是读出一个字节。lz可以自己好好看看文档。 文本文件的信息是当作字符串的形式保存的,比如文本文件里的1,所以以字节的方式读出来,就是‘1’这个字符的ascii码,以字符串的形式读取出来才是“1” 如果想以字符串的形式读入信息,可以改用BufferedReader的readLine(按文本每行读入)或用Scanner的nextLine(按文本每行读入)或nextInt(按单个int类型读入),比如 BufferedReader br = new InputStreamRrader(inputStream); String s=null; while((s=br.readLine())!=null) { int data = Integer.valueOf(s); //前提是文本按int+换行的形式保存 list.add(data); } 或者 Scanner sc = new Scanner(new File(filename)); while(sc.hasNext()) { int data = sc.nextInt();//前提是文本按int+空格或换行的形式保存数据 list.add(data); }

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧