java文件读取内容转码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java文件读取内容转码相关的知识,希望对你有一定的参考价值。
public static void main(String[] args) throws IOException
// TODO Auto-generated method stub
File file=new File("F://svn//Test.properties");
InputStream io=new FileInputStream(file);
byte[] buf=new byte[(int)file.length()];
io.read(buf);
String str=new String(buf);
byte[] str1=str.getBytes();
//String str="\u8fd9\u662f\u4e00\u4e2a\u5bc6\u7801";
System.out.println(str.length());
System.out.println("file.encoding:" + System.getProperty("file.encoding"));
String st=transaction(str1);
System.out.println(st);
protected static String transaction(byte[] filename)
String str=null;
try
str=new String(filename,"UTF-8");
catch (UnsupportedEncodingException e)
// TODO Auto-generated catch block
e.printStackTrace();
return str;
就这样一个代码,为什么从文件中读取得到的String,查看length得到的是36,转码得不到预期结果。
//String str="\u8fd9\u662f\u4e00\u4e2a\u5bc6\u7801";
而直接写在代码里面的String,length是6,转码成功为“这是一个密码”
可以通过BufferedReader 流的形式进行流缓存,之后通过readLine方法获取到缓存的内容。
BufferedReader bre = null;
try
String file = "D:/test/test.txt";
bre = new BufferedReader(new FileReader(file));//此时获取到的bre就是整个文件的缓存流
while ((str = bre.readLine())!= null) // 判断最后一行不存在,为空结束循环
System.out.println(str);//原样输出读到的内容
;
bre.close(),//关闭流,否则bre流会一直存在,直到程序运行结束。
除此之外,java文件读取的时候有中文就很出现乱码,通常获取到的文件中通常都是“iso8859-1”格式,需要转换为“UTF-8”格式。
如:String str = new String(str.getByte("iso8859-1"),"UTF-8");进行下强制转换后在进行读取即可。
备注:通常格式有GBK、UTf-8、iso8859-1、GB2312,如果上面的强制转换不成功,依次进行这些格式的尝试,肯定是可以解决问题的。 参考技术A 打散重装就好了。
/**
* 编码:输入一个字符串,返回编码后的字符串
*
* @author qinzy
* @param str
* @return
*/
public static String encode(String str)
if (str == null || "".equals(str))
return str;
try
str = URLEncoder.encode(str, "UTF-8");
catch (UnsupportedEncodingException e1)
e1.printStackTrace();
return str;
/**
* 编码:输入一个字符串,返回两次编码后的字符串
*
* @author qinzy
* @param str
* @return
*/
public static String encode2(String str)
if (str == null || "".equals(str))
return str;
try
str = URLEncoder.encode(URLEncoder.encode(str, "UTF-8"), "UTF-8");
catch (UnsupportedEncodingException e1)
e1.printStackTrace();
return str;
/**
* 解码:输入一个字符串,返回解码后的字符串
*
* @author qinzy
* @param str
* @return
*/
public static String decode(String str)
if (str == null || "".equals(str))
return str;
try
str = URLDecoder.decode(str, "UTF-8");
catch (UnsupportedEncodingException e1)
e1.printStackTrace();
return str;
追问
打散重装?是将一个字的截取出来再重新组成一个新的字符串?
追答我给你的这3个方法你看了么 前两个方法就是打散重装,就是将一个字符串打散成2进制编码,再重新组装成自己想要的编码格式。这样能防止乱码的产生。
追问用第一个方法得到
%5Cu8fd9%5Cu662f%5Cu4e00%5Cu4e2a%5Cu5bc6%5Cu7801
用第二个方法得到
%255Cu8fd9%255Cu662f%255Cu4e00%255Cu4e2a%255Cu5bc6%255Cu7801
用第三个方法得到
\u8fd9\u662f\u4e00\u4e2a\u5bc6\u7801
即使在第一个方法后用第三个方法也得到\u8fd9\u662f\u4e00\u4e2a\u5bc6\u7801
却不是想要的:这是一个密码
在java中汉字在后台是以16进制存储的,你这个是16进制的代码。你只要直接输出
String a = "\u8fd9";
System.out.println(a);
就能输出汉字“这”了。写到文件里也是这样。
Python基础3 文件操作字符编码与转码
文件操作
对文件操作过程
打开文件,得到文件句柄赋值给变量
操作
关闭文件
打开文件的模式有:
r,只读模式(默认)。
w,只写模式。【不可读;不存在则创建;存在则删除内容;】
a,追加模式。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
r+,可读写文件。【可读;可写;可追加】
w+,写读
a+,同a
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
rU
r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
rb
wb
ab
#文件句柄
f = open(‘yesterday‘,‘r‘,encoding=‘utf-8‘)
#r模式为读模式
f = open(‘yesterday‘,‘r‘,encoding=‘utf-8‘)
#w模式为写,创建文件
f = open(‘yesterday2‘,‘w‘,encoding=‘utf-8‘)
f.write("我爱北京天安门,\n")
f.write("天安门上太阳升\n")
#a模式为追加,创建文件
f = open(‘yesterday2‘,‘a‘,encoding=‘utf-8‘)
f.write("我爱北京天安门,\n")
f.write("天安门上太阳升\")
#关闭文件
f.close()
#读前5行
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
for i in range(5):
print (f.readline())
# 循环读每行
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
for i in f.readlines():
print (i,)
# 读前9行
count = 0
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
for line in f:
if count == 9:
print (‘------我是分割线-------‘)
count += 1
continue
print (line.strip())
count += 1
#seek和tall用法
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
print (f.tell())
print (f.readline().strip())
print (f.readline().strip())
print (f.readline().strip())
print (f.tell())
f.seek(0)
print (f.readline().strip())
#强制刷新保存
f.flush()
#截断
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
f.truncate(10)
#读写,r+,读和追加
f = open(‘yesterday2‘,‘r+‘,encoding=‘utf-8‘)
print (f.readline())
print (f.readline())
print (f.readline())
f.write(‘-----diao----\n‘)
print (f.readline())
#写读,w+,先创建一个文件
f = open(‘yesterday2‘,‘w+‘,encoding=‘utf-8‘)
f.write(‘-----diao----\n‘)
f.write(‘-----diao----\n‘)
f.write(‘-----diao----\n‘)
f.write(‘-----diao----\n‘)
print (f.tell())
f.seek(10)
print (f.readline())
f.write(‘should\n‘)
#追加读,a+
#读二进制文件
f = open(‘yesterday2‘,‘rb‘)
print (f.readline())
#写二进制文件
f = open(‘yesterday2‘,‘wb‘)
f.write(‘hello\n‘.encode(‘utf-8‘))
f.close()
#文件修改
f = open(‘yesterday2‘,‘r‘,encoding=‘utf-8‘)
f_new = open(‘yesterday3‘,‘w‘,encoding=‘utf-8‘)
for line in f:
if ‘肆意的快乐‘ in line:
line = line.replace(‘肆意的快乐等我享受‘,‘肆意的快乐等xxx享受‘)
f_new.write(line)
f.close()
with语句
with open(‘file_name‘, r) as f:
...
# 在Python 2.7 后,with又支持同时对多个文件的上下文进行管理
with open(‘log1‘) as obj1, open(‘log2‘) as obj2:
...
字符编码与转码
需知:
在python2默认编码是ASCII, python3里默认是unicode
unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-8,因为utf8省空间
在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string
python2
#-*-coding:utf-8-*-
import sys
print(sys.getdefaultencoding())
msg = "我爱北京天安门"
msg_gb2312 = msg.decode("utf-8").encode("gb2312")
gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk")
print(msg)
print(msg_gb2312)
print(gb2312_to_gbk)
python3
#-*-coding:gb2312 -*- #这个也可以去掉
import sys
print(sys.getdefaultencoding())
msg = "我爱北京天安门"
#msg_gb2312 = msg.decode("utf-8").encode("gb2312")
msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔
gb2312_to_unicode = msg_gb2312.decode("gb2312")
gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8")
print(msg)
print(msg_gb2312)
print(gb2312_to_unicode)
print(gb2312_to_utf8)
赋值及深浅拷贝
对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址
赋值
#赋值
#n1 n2指向同一内存地址,修改n1后n2依然指向之前的内存地址,n1内存地址变了
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1
print(id(n1))
print(id(n2))
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
print(id(n1))
print(id(n2))
print(n2)
浅拷贝
#复制列表,浅copy
#增加一个内存指针指向已经存在的内存,只影响第一层
names = [‘ZhangYang‘,‘ZhaoYi‘,‘ShaoYiFan‘,‘JiaChen‘,‘MengLingJun‘,‘LiuLin‘,[‘YangRui‘]]
names2 = names.copy()
print (names,names2)
import copy
#浅copy,3中方式
person = [‘name‘,[‘saving‘,100]]
‘‘‘
p1 = copy.copy(person)
p2 = person[:]
p3 = list(person)
‘‘‘
p1 = person[:]
p2 = person[:]
p1[0] = ‘tom‘
p2[0] = ‘jane‘
p1[1][1] = 50
print (p1)
print (p2)
深拷贝
import copy
#复制列表,深copy
#增加一个内存指针并申请一块新的内存
names2 = copy.deepcopy(names)
names[3] = ‘汤姆‘
names[-1][0] = ‘杰克‘
print (names)
print (names2)
以上是关于java文件读取内容转码的主要内容,如果未能解决你的问题,请参考以下文章
FFmpeg本地任意文件读取漏洞 / FFmpeg Local arbitrary file read vulnerability