例3.EncodeDemo3.java
public class EncodeDemo3 {
/**
* 功能:将字符串转换成二进制数
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception{
String s = "联通";
String ss = "q";
byte[] b = ss.getBytes("gbk");
for (int i = 0; i < b.length; i++) {
System.out.println("q的二进制为:"+Integer.toBinaryString(b[i]));
}
byte [] by = s.getBytes("gbk");
for (int i = 0; i < by.length; i++) {
System.out.println(by[i]+"的二进制数为:");
//将4个数字转换成二进制打印出来
System.out.println(Integer.toBinaryString(by[i]));
System.out.println("取后8位为:"+Integer.toBinaryString(by[i]&255));
System.out.println("==============================");
}
}
}
例4.InputStreamReaderBigFile.java
/** 读取大文件
* 功能:用java读取文件的全部内容,读取的内容较多时,不能一个字符一个字符地读,可以一次读一行。
*/
import java.io.*;
public class InputStreamReaderBigFile {
public static void main(String args[]) throws Exception{
readText();
}
public static void readText() throws Exception{
//假定utf-8.txt文件已存在,并且写入时是以utf-8的方式编码。
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");
//BufferedReader这个对象,可以一次读取一行
BufferedReader br = new BufferedReader(isr);
String str;
while((str = br.readLine())!=null){
System.out.println(str);
}
br.close();
isr.close();
}
}
例5.OutputStreamWriterGBK.java
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* 功能:将字符串写入到指定文件中 ,主要是理解写文件时编码
* @author Administrator
*
*/
public class OutputStreamWriterGBK {
public static void main(String args[]) throws Exception{
osw();
}
public static void osw() throws Exception{
try {
//缺省编码方式为操作系统的字符集gbk,所以gbk可以不写
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
//调用父类Writer的write()方法
osw.write("您好");
osw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
例6.InputStreamReaderGBK.java
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* 功能:用字符char的方式读出gbk.txt文件中内容,并以gbk的方式读取。主要是理解读文件时解码
* @author Administrator
*
*/
public class InputStreamReaderGBK {
public static void main(String []arg) throws Exception{
isr();
}
public static void isr() throws Exception{
InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"),"gbk");
//unicode:一个字符占2个字节,1个字节占8位
//因为知道了gbk.txt中的内容少,故在此用char来读取
char [] buf = new char[10];
int len = isr.read(buf);
System.out.println("gbk.txt文件内容长度为:"+len+"个字符");
String string = new String(buf,0,len);
System.out.println(string);
isr.close();
}
}
例7.OutputStreamWriterUTF8.java
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* 功能:将字符串写入到指定文件中 。理解写入字符到文件时的编码,以utf-8
* @author Administrator
*
*/
public class OutputStreamWriterUTF8 {
public static void main(String args[]) throws Exception{
osw();
}
public static void osw() throws Exception{
try {
//缺省编码方式为操作系统的字符集gbk,因为创建utf-8.txt文件时,指定了utf-8的编码,所以在此必须明确写上utf-8的编码方式
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf-8.txt"),"utf-8");//在这个地方进行转码操作
osw.write("您好");
osw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
完例7相同的将字符串写入文件功能。但用了不同的实现方式。
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class WriteFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
OutputStream out=new FileOutputStream(f);
String s = "我们";
//表示以操作系统默认字符集编码方式写入文件
//out.write(s.getBytes());
//表示以utf-8的编码方式写入文件。以后读取文件内容时,也必须用utf-8进行解码读取。将字符串转换字节的方式
//s.getBytes("utf-8")表示将一字节数组写进去
out.write(s.getBytes("utf-8"));//在这个地方进行设置编码
out.close();
}
}
当然,上面的代码也可修改成一个字节一个字节地进行写入:
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class WriteFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
OutputStream out = new FileOutputStream(f);
String s = "我们";
//表示以操作系统默认字符集编码方式写入文件
//in.write(s.getBytes());
//表示以utf-8的编码方式写入文件。以后读取文件内容时,也必须用utf-8进行解码读取。将字符串转换字节的方式
//s.getBytes("utf-8")表示将一字节数组写进去
// out.write(s.getBytes("utf-8"));//在这个地方进行设置编码
byte[] b = s.getBytes("utf-8");
for(int i=0; i
out.write(b[i]);
}
out.close();
}
}
最后,我们用字符流的方式将内容写入文件。不需要转码操作。请看如下代码。
import java.io.*;
public class WriteFile{
public static void main(String [] args){
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
Writer w = new FileWriter(f);
String str = "hello";
w.write(str);
w.close();
}
}
例8.InputStreamReaderUTF8.java
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* 功能:用字符char的方式读出gbk.txt文件中内容,并以utf-8的方式读取 。理解读取文件中的内容解码 utf-8方式
* 将字节流转换字符流的方式进行读取文件中的内容
* @author Administrator
*
*/
public class InputStreamReaderUTF8 {
public static void main(String []arg) throws Exception{
isr();
}
public static void isr() throws Exception{
//指定以utf-8的方式创建一个输入流.目的在于注意区分,如果创建文件时指定了gbk编码方式,而读取时如果指定别的编码方式,则会产生乱码。
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8"); //在这个地方进行解码,将字节流转换为字符流 //unicode:一个字符占2个字节,1个字节占8位
//因为知道了gbk.txt中的内容少,故在此用char来读取
char [] buf = new char[10];
int len = isr.read(buf);
System.out.println("utf-8.txt文件内容长度为:"+len+"个字符");
String string = new String(buf,0,len);
System.out.println(string);
isr.close();
}
}
与例8完成相同的读取文件内容功能,但用了不同的实现方式:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 功能:完成解码与编码,以字节流的方式读取文件内容
* @author Administrator
*
*/
public class ReadFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
byte[] b=new byte[1030];
//将文件的内容读到b数组中
in.read(b);
in.close();
//如果源文件的编码方式是utf-8方式,读取时,必须指定以同样的编码方式进行解码。否则就会乱码
System.out.println(new String(b,"utf-8")); //在这个地方进行解码
/*用下面的方式进行显示,就会有乱码System.out.println(new String(b,"gbk"));System.out.println(new String(b));*/
}
}
上述程序代码读的时候,会有大量的空格,我们可以利用in.read(b);的返回值来设计程序。如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 功能:完成解码与编码。以字节流的方式读取文件内容
* @author Administrator
*
*/
public class ReadFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
byte[] b=new byte[1030];
int len = in.read(b);
in.close();
System.out.println("读取文件的长度为:"+len);
//如果源文件的编码方式是utf-8方式,读取时,必须指定以同样的编码方式进行解码。否则就会乱码
System.out.println(new String(b,0,len,"utf-8")); //在这个地方进行解码
/*用下面的方式进行显示,就会有乱码System.out.println(new String(b,"gbk"));System.out.println(new String(b));*/
}
}
仔细观察上面的代码可以看出,我们预先申请了一个指定大小空间。但是,有可能这个空间太小,有时候可能太大。我们更需要准确的大小,这样可以节省空间。请看如下代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 功能:完成解码与编码。以字节流的方式读取文件内容。根据文件长度来创建数据大小
* @author Administrator
*
*/
public class ReadFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
// byte[] b=new byte[1030];
//f.length();表示返回由此抽象路径名表示的文件的长度。(int)f.length();表示进行数据类型的转换。
//定义一个不定长的字节数组。长度根据文件的长度来创建
byte [] b = new byte[(int)f.length()];
in.read(b);
in.close();
System.out.println("文件的长度为:"+f.length());
//如果源文件的编码方式是utf-8方式,读取时,必须指定以同样的编码方式进行解码。否则就会乱码
System.out.println(new String(b,"utf-8")); //在这个地方进行解码
/*用下面的方式进行显示,就会有乱码
System.out.println(new String(b,"gbk"));
System.out.println(new String(b));
*/
}
}
再将上述代码进行优化,一个字节一个字节地读。更节省空间。看如下代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 功能:完成解码与编码。以字节流的方式读取文件内容。一个字节一个字节地读
* @author Administrator
*
*/
public class ReadFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
// byte[] b=new byte[1030];
//f.length();表示返回由此抽象路径名表示的文件的长度。(int)f.length();表示进行数据类型的转换。
//定义一个不定长的字节数组。长度根据文件的长度来创建
byte [] b = new byte[(int)f.length()];
for ( int i = 0; i
// in.read(b);
in.close();
System.out.println("文件的长度为:"+f.length());
//如果源文件的编码方式是utf-8方式,读取时,必须指定以同样的编码方式进行解码。否则就会乱码
System.out.println(new String(b,"utf-8")); //在这个地方进行解码
/*用下面的方式进行显示,就会有乱码
System.out.println(new String(b,"gbk"));
System.out.println(new String(b));
*/
}
}
再仔细想:当我们不知道文件有多大时,这种情况下,需要判断是否读到文件末尾。采用while循环。请看如下代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 功能:完成解码与编码。以字节流的方式读取文件内容。增加判断,是否读到文件末尾
* @author Administrator
*
*/
public class ReadFile {
public static void main(String[] args) throws Exception {
//假定utf-8.txt文件的编码方式是以utf-8方式编码的
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
byte[] b=new byte[1030];
int i= 0;
int tmp = 0;
while (( tmp=in.read())!= (-1)){
//整型强制转换成byte型.每循环一次,字节数组中就增加一个元素
b[i++} = (byte)tmp;
}
//f.length();表示返回由此抽象路径名表示的文件的长度。(int)f.length();表示进行数据类型的转换。
//定义一个不定长的字节数组。长度根据文件的长度来创建
/* byte [] b = new byte[(int)f.length()];
for ( int i = 0; i
b[i] = in.read();
}*/
// in.read(b);
in.close();
System.out.println("文件的长度为:"+f.length());
//如果源文件的编码方式是utf-8方式,读取时,必须指定以同样的编码方式进行解码。否则就会乱码
System.out.println(new String(b,"utf-8")); //在这个地方进行解码
/*用下面的方式进行显示,就会有乱码
System.out.println(new String(b,"gbk"));
System.out.println(new String(b));
*/
}
}
最后,以字符的方式从文件中读取内容。看如下代码:
public class ReadFile{
public static void main(String [] args){
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
char [] ch = new char[100];
Reader r = new FileReader(f);
int count = r.read(ch);
r.close();
System.out.println("读入的长度为:"+count);
System.out.println("内容为:"+new String(ch,0,count));
}
}
有时候,我们还不知道文件到底有多大,所以,我们更宜采用循环的方式读取(以字符方式读取)。看如下代码:
public static void main(String [] args){
String fileName="D:"+File.separator+"Workspaces"+File.separator+"charset"+File.separator+"utf-8.txt";
File f=new File(fileName);
char [] ch = new char[100];
Reader r = new FileReader(f);
int tmp = 0;
int i = 0;
while ((tmp = r.read())!= (-1)){
ch[i++] = (char)tmp;
}
// int count = r.read(ch);
r.close();
//System.out.println("读入的长度为:"+count);
System.out.println("内容为:"+new String(ch,0,count));
}
}
关于字节流和字符流的区别实际上字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的,但是字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件的。读者可以试着将上面的字节流和字符流的程序的最后一行关闭文件的代码注释掉,然后运行程序看看。你就会发现使用字节流的话,文件中已经存在内容,但是使用字符流的时候,文件中还是没有内容的,这个时候就要刷新缓冲区。使用字节流好还是字符流好呢?答案是字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
延伸:文件的复制。基本思路还是从一个文件中读入内容,边读边写入另一个文件,就是这么简单.请看ReadANDWrite.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
/*
*功能:将一个文件的内容读出来后,将所有内容写入到另一个文件。实现文件复制功能
*/
public class ReadANDWrite {
public static void main(String []args) throws Exception{
File file = new File("c:\\gbk.txt");
InputStream is = new FileInputStream(file);
//OutputStream os = new FileOutputStream(new File("c:\\gbk-copy.txt"));
Writer writer = new OutputStreamWriter(new FileOutputStream("c:\\gbk-copy.txt"));
byte [] b = new byte[100];
//int len = is.read(b);
int len;
int i=0;
//循环判断是否读到文件末尾
while ((len = is.read())!=(-1)) {
// String s = new String(b);
// writer.write(s);
//设置计数器。看看总共有几个字节
int c = i++;
//按字节进行读取,读到一个字节后,赋值给字节数组变量
b[c] = (byte)len;
System.out.println("b"+"["+i+"]"+":"+b[c]);
}
//将字节数组转换成字符串,为了不出现多余的空格,必须需要接上加上相关参数,从哪开始读,读到哪结束
String s = new String(b,0,i);
writer.write(s);
System.out.println(new String(b,0,i));
//os.write((byte)is.read(b));
is.close();
writer.close();
//os.close();
}
}