关于java文件操作API的选择和编码问题

一、java读文件内容

1、按字节读取文件内容 :以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件(可以一次读取一个字节和一次读取多个字节放在字节数组中)


2、按字符读取文件内容: 以字符为单位读取文件,常用于读文本,数字等类型的文件
(同样一次读取一个字符或读取多个字符放在字符数组中)


3、按行读取文件内容 :以行为单位读取文件,常用于读面向行的格式化文件
   jdk说明:
public class BufferedReader extends Reader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,

BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
通过用合适的 BufferedReader 替代每个 DataInputStream,可以对将 DataInputStream 用于文字输入的程序进行本地化。



4、随机读取文件内容 :这一种方法不常用,是随机读取的方式,这种方式比较特殊,他不隶属于InputStream,OutputStream类系,他是直接继承自Object类的。RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream粘起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件,从这一点上看,假如RandomAccessFile继承了DataInputStream,它也许会干得更好。

参考代码如下:RandomAccessFile read = new RandomAccessFile(args,"r");  
        RandomAccessFile writer = new RandomAccessFile(args,"rw");  
        byte[] b = new byte;
        int count;
        while((count=read.read(b))!=-1){ 
                //System.out.println(count);
                if(count!=b.length)
                {
                        byte[] t=new byte;
                        for(int i=0;i<count;++i)
                                t=b;
                        writer.write(t);
                }
                else writer.write(b);  
        }  
        writer.close();  
        read.close();参数选择可以根据后边标记读写的进行选择,比如说第二个参数是"r",说明这是一个读文件的,如果是"rw",说明是写文件的。


对于大文件参考:Java IO读写大文件的几种方式及测试 http://justsee.iteye.com/blog/1452502

二、文件操作中的编码问题

1.通常指定文件操作编码

如:
InputStreamReader streamReader = new InputStreamReader(ipts, "GBK");
InputStreamReader streamReader = new InputStreamReader(ipts, "utf-8");
指定编码的前提是知道了要操作文件的编码格式

Java读取文件的方式总体可以分为两类:按字节读取和按字符读取。按字节读取就是采用InputStream.read()方法来读取字节,然后保存到一个byte[]数组中,最后经常用new String(byte[]);把字节数组转换成String。在最后一步隐藏了一个编码的细节,new String(byte[]);会使用操作系统默认的字符集来解码字节数组,中文操作系统就是GBK。而我们从输入流里读取的字节很可能就不是GBK编码的,因为从输入流里读取的字节编码取决于被读取的文件自身的编码。举个例子:我们在D:盘新建一个名为demo.txt的文件,写入”我们。”,并保存。此时demo.txt编码是ANSI,中文操作系统下就是GBK。此时我们用输入字节流读取该文件所得到的字节就是使用GBK方式编码的字节。那么我们最终new String(byte[]);时采用平台默认的GBK来编码成String也是没有问题的(字节编码和默认解码一致)。试想一下,如果在保存demo.txt文件时,我们选择UTF-8编码,那么该文件的编码就不在是ANSI了,而变成了UTF-8。仍然采用输入字节流来读取,那么此时读取的字节和上一次就不一样了,这次的字节是UTF-8编码的字节。两次的字节显然不一样,一个很明显的区别就是:GBK每个汉字两个字节,而UTF-8每个汉字三个字节。如何我们最后还使用new String(byte[]);来构造String对象,则会出现乱码,原因很简单,因为构造时采用的默认解码GBK,而我们的字节是UTF-8字节。正确的办法就是使用new String(byte[],”UTF-8”);来构造String对象。此时我们的字节编码和构造使用的解码是一致的,不会出现乱码问题了。

   这个是网上的搜索的解决方法,但是如果有时候在utf-8编码环境中还是会出现乱码问题,Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决:
  解决办法:

使用UltraEdit将上边的txt文件另存为UTF-8无BOM格式;或者
使用Notepad++打开上边的txt文件执行如下操作“格式-->以UTF-8无BOM格式编码”,修改后将txt文本进行保存






你可能感兴趣的:(java)