字节流

【向文件中写入字符串】

/**
 * 字节流
 * 向文件中写入字符串
 * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName="D:"+File.separator+"hello.txt";
        File f=new File(fileName);
        OutputStream out =new FileOutputStream(f);
        String str="你好";
        byte[] b=str.getBytes();
        out.write(b);
        out.close();
    }
}

查看hello.txt会看到“你好”

当然也可以一个字节一个字节的写。

/**
 * 字节流
 * 向文件中一个字节一个字节的写入字符串
 * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName="D:"+File.separator+"hello.txt";
        File f=new File(fileName);
        OutputStream out =new FileOutputStream(f);
        String str="你好";
        byte[] b=str.getBytes();
        for (int i = 0; i < b.length; i++) {
            out.write(b[i]);
        }
        out.close();
    }
}
结果还是:“你好”


向文件中追加新内容:

/**
 * 字节流
 * 向文件中追加新内容:
 * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName="D:"+File.separator+"hello.txt";
        File f=new File(fileName);
        OutputStream out =new FileOutputStream(f,true);
        String str="Rollen";
        //String str="\r\nRollen";  可以换行
        byte[] b=str.getBytes();
        for (int i = 0; i < b.length; i++) {
            out.write(b[i]);
        }
        out.close();
    }
}

【运行结果】:

你好Rollen

【读取文件内容】
/**
* 字节流
* 读文件内容
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
InputStream in=newFileInputStream(f);
byte[] b=newbyte[1024];
in.read(b);
in.close();
System.out.println(newString(b));
}
}


【运行结果】

你好Rollen

Rollen_

但是这个例子读取出来会有大量的空格,我们可以利用in.read(b);的返回值来设计程序。如下:

/**
* 字节流
* 读文件内容
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
InputStream in=newFileInputStream(f);
byte[] b=newbyte[1024];
intlen=in.read(b);
in.close();
System.out.println("读入长度为:"+len);
System.out.println(newString(b,0,len));
}
}

【运行结果】:

读入长度为:18

你好Rollen

Rollen


读者观察上面的例子可以看出,我们预先申请了一个指定大小的空间,但是有时候这个空间可能太小,有时候可能太大,我们需要准确的大小,这样节省空间,那么我们可以这样干:

/**
* 字节流
* 读文件内容,节省空间
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
InputStream in=newFileInputStream(f);
byte[] b=newbyte[(int)f.length()];
in.read(b);
System.out.println("文件长度为:"+f.length());
in.close();
System.out.println(newString(b));
}
}

文件长度为:18

你好Rollen

Rollen

将上面的例子改为一个一个读:
/**
* 字节流
* 读文件内容,节省空间
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
InputStream in=newFileInputStream(f);
byte[] b=newbyte[(int)f.length()];
for(inti = 0; i < b.length; i++) {
b[i]=(byte)in.read();
}
in.close();
System.out.println(newString(b));
}
}


输出的结果和上面的一样。


细心的读者可能会发现,上面的几个例子都是在知道文件的内容多大,然后才展开的,有时候我们不知道文件有多大,这种情况下,我们需要判断是否独到文件的末尾。

/**
* 字节流
*读文件
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
InputStream in=newFileInputStream(f);
byte[] b=newbyte[1024];
intcount =0;
inttemp=0;
while((temp=in.read())!=(-1)){
b[count++]=(byte)temp;
}
in.close();
System.out.println(newString(b));
}
}

【运行结果】

你好Rollen

Rollen_

提醒一下,当独到文件末尾的时候会返回-1.正常情况下是不会返回-1的


字符流

【向文件中写入数据】

现在我们使用字符流

/**
* 字符流
* 写入数据
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
Writer out =newFileWriter(f);
String str="hello";
out.write(str);
out.close();
}
}

当你打开hello。txt的时候,会看到hello

其实这个例子上之前的例子没什么区别,只是你可以直接输入字符串,而不需要你将字符串转化为字节数组。

当你如果想问文件中追加内容的时候,可以使用将上面的声明out的哪一行换为:

Writer out =new FileWriter(f,true);

这样,当你运行程序的时候,会发现文件内容变为:

hellohello如果想在文件中换行的话,需要使用“\r\n”

比如将str变为String str="\r\nhello";

这样文件追加的str的内容就会换行了。


从文件中读内容:


/**
* 字符流
* 从文件中读出内容
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
char[] ch=newchar[100];
Reader read=newFileReader(f);
intcount=read.read(ch);
read.close();
System.out.println("读入的长度为:"+count);
System.out.println("内容为"+newString(ch,0,count));
}
}


【运行结果】:

读入的长度为:17

内容为hellohello

hello


当然最好采用循环读取的方式,因为我们有时候不知道文件到底有多大。

/**
* 字符流
* 从文件中读出内容
* */
importjava.io.*;
classhello{
publicstaticvoidmain(String[] args) throwsIOException {
String fileName="D:"+File.separator+"hello.txt";
File f=newFile(fileName);
char[] ch=newchar[100];
Reader read=newFileReader(f);
inttemp=0;
intcount=0;
while((temp=read.read())!=(-1)){
ch[count++]=(char)temp;
}
read.close();
System.out.println("内容为"+newString(ch,0,count));
}
}

运行结果:

内容为hellohello

hello


关于字节流和字符流的区别

实际上字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的,但是字符流在操作的 时候下后是会用到缓冲区的,是通过缓冲区来操作文件的。

读者可以试着将上面的字节流和字符流的程序的最后一行关闭文件的代码注释掉,然后运行程序看看。你就会发现使用字节流的话,文件中已经存在内容,但是使用字符流的时候,文件中还是没有内容的,这个时候就要刷新缓冲区。

使用字节流好还是字符流好呢?

答案是字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。