官方微博:动力节点
遇到的问题
在用socket通信传输一个pdf文件以及其他的非txt文件的时候总是传到服务端的文件出错,后来发现是在用字符流和字节流在读取各种文件上的差别所导致的。
java读取文件的方式
1.字节流读取:InputStream和OutPutStream,其读取的方式按字节读取,这个常用于读取原始数据。
2.字符流读取:Reader和Writer,按字节读取数据,java里面一个字符对应两个字节。
为什么会有时候会出现乱码
在计算机中常会涉及到编码问题,那么在字符流读取文件的时候也会遇到一些问题,典型的就是在读取txt文件的时候再保存遇到的乱码,在java里面一个字符对应两个字节,但是在UTF-8的编码中有时候一个汉字可能对应的是三个字节,那么这个时候在读取的时候不指定编码的话会造成读取文件的乱码现象。
一个txt文件假设是GBK编码的话,在以字符流读取的时候若依GBK读取就会造成问题。
测试(JDK1.8,IDEA,默认编码UTF-8,txt文件编码GBK)
测试一
写了一个代码测试了下: 在以字节流去读取pdf格式和其他格式的文件都没问题,但是字节流读取之后保存为String再写入文件会导致pdf等文件出错:代码如下:
此时会导致pdf文件全部是白的,音乐等文件全部错误,而且txt格式的文件的文字全部变成拷斤棍,至于拷斤棍百度了下是由于字符编码问题
测试二
将读取之后的String再次变为字节流然后再进行读取再直接以字节流写入:此时如同前面一个代码结果一样,除了txt有编码问题之外的文件都有问题。
测试三:
全部以GBK格式读取和以GBK格式写入,除了txt文件正常以外其他的文件全部出错。
File file1 =new File("D:\\disk\\1\\Java锁.txt");
File file1 =new File("D:\\disk\\1\\README.doc");
File file2 =new File("D:\\disk\\test4.doc");
FileInputStream fileInputStream =new FileInputStream(file1);
Reader reader =new InputStreamReader(fileInputStream,"GBK");
char[] chars =new char[1024]; int read=0;
StringBuffer sb =new StringBuffer(); while((read=reader.read(chars))!= -1)
{
sb.append(new String(chars,0,read));
}
FileOutputStream fileOutputStream =new FileOutputStream(file2);
Writer writer =new OutputStreamWriter(fileOutputStream,"GBK");
writer.write(sb.toString());
writer.flush();
writer.close();
所以在java里面对文件的读写最好以字节流写入:此时无论是各种文件都没问题,对于字符流的使用感觉是在一些需要编码的文件,即类似于txt的文本文件。
全部代码
import java.io.*;/**
* Created by szh on 2017/3/26.
*/public class FileTest {
public static void tes() throws IOException {
File file1 =new File("D:\\disk\\1\\README.doc");
File file2 =new File("D:\\disk\\tes.doc");
Reader reader =new InputStreamReader(new FileInputStream(file1)); int len; char[] a =new char[1024];
StringBuffer sb =new StringBuffer(); while ((len=reader.read(a))!= -1)
{
sb.append(new String(a,0,len));
}
reader.close();
FileWriter fileWriter = new FileWriter(file2);
fileWriter.write(sb.toString());
fileWriter.flush();
fileWriter.close();
}
public static void test2() throws IOException {
File file1 =new File("D:\\disk\\1\\README.doc");
File file2 =new File("D:\\disk\\test2.doc"); byte[] sendBytes = new byte[1024]; int length = 0;
StringBuffer sb =new StringBuffer();
FileInputStream fileInputStream =new FileInputStream(file1); while((length = fileInputStream.read(sendBytes, 0, sendBytes.length))
|