Java BufferedReader读取UTF-8文件中文乱码

本文介绍了解决在Java程序中读取文本文件时遇到的中文乱码问题的方法,通过设置正确的文件编码格式(UTF-8无BOM)避免了乱码及额外字符的出现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一个项目中,需要读取一个文本文件,但是每次读取到的内容,,中文总是乱码,于是找了下解决方法:

原先读取的代码:
BufferedReader read = new BufferedReader(new FileReader(new File(filename)));

line = read.readLine();

解决办法:
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader read = new BufferedReader(isr);

line = read.readLine();

这样修改之后,可以读取中文了,没有出现乱码,但是第一行总是会出现一个?在第一个字符的位置。。。。无语。。

于是继续找资料,发现是格式的问题,将文件用编辑器打开,保存为UTF-8无bom格式就行了。


对于这个格式,有兴趣了解的可以继续往下看:

BOM——Byte Order Mark,就是字节序标记在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。UTF-8编码的文件中,BOM占三个字节。如果用记事本把一个文本文件另存为UTF-8编码方式的话,用UE打开这个文件,切换到十六进制编辑状态就可以看到开头的FFFE了。这是个标识UTF-8编码文件的好办法,软件通过BOM来识别这个文件是否是UTF-8编码,很多软件还要求读入的文件必须带BOM。可是,还是有很多软件不能识别BOM。在Firefox早期的版本里,扩展是不能有BOM的,不过Firefox 1.5以后的版本已经开始支持BOM了。现在又发现,PHP也不支持BOM。PHP在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头BOM的那三个字符。由于必须在在Bo-Blog的wiki看到,同样使用PHP的Bo-Blog也一样受到BOM的困扰。其中有提到另一个麻烦:“受COOKIE送出机制的限制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效。一切依赖COOKIE、SESSION实现的功能全部无效。”这个应该就是Wordpress后台出现空白页面的原因了,因为任何一个被执行的文件包含了BOM,这三个字符都将被送出,导致依赖cookies和session的功能失效。解决的办法嘛,如果只包含英文字符(或者说ASCII编码内的字符),就把文件存成ASCII码方式吧。用UE等编辑器的话,点文件->转换->UTF-8转ASCII,或者在另存为里选择ASCII编码。如果是DOS格式的行尾符,可以用记事本打开,点另存为,选ASCII编码。如果包含中文字符的话,可以用UE的另存为功能,选择“UTF-8 无 BOM”即可。

### 使用Python实现12306抢票和开票功能 #### 抢票功能的技术挑战与解决方案 开发针对特定平台如12306的自动化工具涉及多个技术难点,包括但不限于验证码识别、登录机制破解以及频繁请求可能导致的服务端封禁IP等问题。对于合法合规的应用场景下,可以考虑通过官方API接口调用来完成订票操作而不是模拟浏览器行为。 然而,在实际应用中,由于铁路部门并未开放此类API给第三方开发者用于自动化的购票流程处理,因此直接提供完整的抢票脚本并不合适也不符合规定[^1]。 为了满足学习目的下的编码练习需求,下面给出一个简化版框架作为参考: ```python import requests from lxml import etree def login(username, password): session = requests.Session() # 假设这里已经实现了获取并解析登录页面所需的隐藏字段逻辑 payload = { 'username': username, 'password': password, # 添加其他必要参数... } response = session.post('https://kyfw.12306.cn/otn/login/userLogin', data=payload) if "欢迎" in response.text: print("登录成功") return session else: raise Exception("登录失败") def search_trains(departure_station, arrival_station, date): url = f'https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice' params = {'train_no': '', 'from_station': departure_station, 'to_station': arrival_station, 'date': date} resp = requests.get(url=url, params=params).json() trains_info = [] for train in resp['data']['result']: info = {} items = str(train).split('|') # 解析列车信息 trains_info.append(info) return trains_info if __name__ == '__main__': sess = login('your_username', 'your_password') # 用户名密码需替换为真实值 available_trains = search_trains('北京', '上海', '2024-01-01') ``` 请注意上述代码仅为示意用途,并未包含全部细节也未经测试验证其有效性;同时强调不得滥用此段代码尝试非法入侵或破坏任何系统服务正常运行秩序的行为。 #### 发票开具部分 关于电子发票申请方面,通常情况下旅客可以在订单完成后按照官方网站指引自行下载打印电子客票报销凭证,无需额外编程介入。如果确实存在定制化的需求,则应该遵循中国国家税务总局发布的相关政策法规指导文件来进行相应的软件集成工作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值