欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java IO 文件与数据流

程序员文章站 2022-06-09 21:13:33
...

java IO 文件与数据流

  • 如果返回char, 那么无法表示流末尾.
  • char的取值范围是从0到65535
  • 这个范围内的所有字符, 都有可能在数据中出现
  • 我们需要使用一个不可能在数据中出现的值来表示流末尾
  • 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现
  • 而为了返回-1, 那么只能用int
  • 当流中读取到一个字符时, read()方法内部就会当作int返回, 如果读到流末尾, 直接返回-1

输入流与输出流

  • 输入流(抽象类 java.io.InputStream):从文件、网络请求返回数据、标准输入、或者其他输入设备中加载到内存中。
  • 输出流(抽象类 java.io.OutputStream):与输入流相反,是从内存输出到文件、显示器、其它输出设备。

InputStream(抽象类)

  • InputStream为抽象类不能创建实例对象,但是InputStream定义了输入流的基本操作,可以通过其子类获得它的实例 。
public class Test {

	public static void echo(InputStream in) {
		try {
			while (true) { // 接受输入并回显
				int i = in.read( );//read()方法每次读取一个字节,读到输入流末尾返回-1
				if (i == -1) // 输入流结束
					break;
				char c = (char) i;
				System.out.print(c);
			}
		} catch (IOException e) {
		    System.err.println("发生异常:" + e);
			e.printStackTrace( );
		}
	}
	
	public static void main(String args[ ]) {
		echo(System.in);
	}
}
  • System.in是java.io.InputStream类型的变量,对应于标准输入;
  • read()方法每次读取一个字节,读到输入流末尾返回-1;
  • System.err.println();是java.io.PrintStream类型的变量,对应标准错误输出流;

OutputStream(抽象类)

  • OutputStream也为抽象类不能创建实例对象,但是OutputStream定义了输入流的基本操作,也可以通过其子类获得它的实例 。
public class Main {

    public static void write(OutputStream out) {
        String s = "输出流例程";
        byte[] b = s.getBytes();
        try {
            out.write(b);
            out.flush();
        } catch (IOException e) {
            System.err.println("发生异常:" + e);
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        write(System.out);
    }
}
  • System.out是java.io.OutputStream类型的变量,对应于标准输出;
  • 在调用write()方法后,常常会调用flush()方法进行强制输出,因为目前的计算机为了提高效率常常采用缓存机制,这样调用write()方法之后,数据不会立即输出,而是暂时保存在缓存中,等积累到一定的程度才会真正输出数据。而调用flush()方法之后是将数据立即输出。

FileInputStream(从文件读取数据)

public class Main {

    public static void main(String args[ ]) {
        try {
            FileInputStream f =new FileInputStream("ex3.txt"); //与文件建立关联
            int i;
            int b = f.read();
            for (i=0; b!=-1; i++) {
                System.out.print((char)b);
                b=f.read();
            }
            System.out.println();
            System.out.println("文件\"test.txt\"字节数为"+i);
            f.close();
        } catch (IOException e) {
            System.err.println("发生异常:" + e);
            e.printStackTrace();
        }
    }
}
  • 文件必须事先存在于项目的目录下,否则会报错;
  • 文件中如果包涵了中文字符的话,中文字符的显示会出错;
  • read()方法的返回值是int类型的。

FileOutputStream(将数据保存到文件中)

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        System.out.println(str);
        byte[] bytes = str.getBytes();
        try{
            FileOutputStream fileOutputStream = new FileOutputStream("ex3.txt",true);
            fileOutputStream.write(bytes);
            fileOutputStream.flush();
            fileOutputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        scanner.close();
    }
  • 文件可以事先存在,才在则直接写入;如果文件不存在的话则新创建文件后将数据写入;
  • 在创建FileOutputStream实例的时候,第二个参数表示是否可追加(false-不可追加,每次写入都是讲原来的覆盖之后再写入,true-则是可以追加,每次写入都是将内容写到文件末尾),第二个参数可以缺省则默认为false.

PrintStream

public static void main(String[] args) {
        try{
            PrintStream printStream = new PrintStream("ex3.txt");
            printStream.printf("%1$d+%2$d=%3$d",1,2,(1+2));//对输出内容进行格式化
            printStream.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
    }
  • Syetem.out是它的一个对象;
  • 文件不要求事先存在,要是文件存在且有内容,则会覆盖内容,要是文件不存在的话,则新创建文件将内容写进去。

数据的输入流和输出流

  • java.io.DataInputStream和java.io.DataOutputStream主要用来读取和存储基本数据类型的数据而且每个基本数据类型数据存储的字节数与他在内存中所占的字节数是相同的;
  • java.io.DataIutputStream的对象通常是由java.io.FireInputStream的实例对象创建的;
  • java.io.DataOutputStream的对象通常是由java.io.FireOutputStream的实例对象创建的;
  • java.io.DataOutputStream的实例其中的方法 write()可以直接将基本数据类型写进指定的文件中,并且字节数与基本数据类型所占字节数相等。例如writeInt()方法用于将int类型的数据写进文件,其他数据类型对应相应的方法。
  • java.io.DataOutputStream的实例其中的方法 reader()可以直接将基本数据类型从文件中读取出来,并且字节数与基本数据类型所占字节数相等。例如readInt()方法用于将int类型的数据从相应文件中读取出来,其他数据类型对应相应的方法。

public static void main(String args[ ]){
        try {
            FileOutputStream fout = new FileOutputStream("out.txt");
            DataOutputStream dfout =new DataOutputStream(fout);
            int i;
            for (i=0; i< 10; i++){
                dfout.writeInt('0' + i);//事先将1-10存入out.txt文件中
            }
            fout.close( );

            FileInputStream fin= new FileInputStream("out.txt");//建立与out.txt关联
            DataInputStream dfin= new DataInputStream(fin);
            for (i=0; i< 10; i++){
                System.out.print(dfin.readInt( ) + ", ");//将out.txt文件中的内容进行输出
            }
            dfin.close( );
        }
        catch (Exception e) {
            System.err.println("发生异常:" + e);
            e.printStackTrace( );
        }
    }

  • java.io.DataOutputStream的writeInt()等方法文件不必事先存在,如果原来文件存在则输出时直接覆盖其中的内容;
  • java.io.DataOutputStream的readInt()等方法如果文件不存在的话,则会抛出异常;

带缓存的输入流输出流

  • 带缓存的输入流输出流所对应的类是:java.io.BufferdInputStream 和 java.io.BufferdOutputStream
  • java.io.BufferedInputStream的对象通常是由java.io.FireInputStream的实例对象创建的,其中size是大于0的整数;
public BufferedInputStream(FileInputStream in);//没有size的话有系统自己指定
public BufferedInputStream(FileInputStream in, int size);
  • java.io.BufferedOutputStream的对象通常是由java.io.FireOutputStream的实例对象创建的,其中size是大于0的整数;
public BufferedOutputStream(FileOutputStream in);//没有size的话有系统自己指定
public BufferedOutputStream(FileOutputStream in, int size);
  • 带缓存的输入输出流兼容抽象类输入输出流的read(),write(),flush()方法。
/**
*对帯与不带缓存在读取数据的效率进行对比
*/
public static void main(String[ ] args) {
        try {
            int i, ch;
            i = 0;
            Date d1= new Date( );
            FileInputStream f = new FileInputStream("J_BufferedInputStream.class");
            while ((ch=f.read( )) != -1){
                i++;
            }
            f.close( );
            Date d2= new Date( );

            long t = d2.getTime( ) - d1.getTime( );
            System.out.printf("读取文件%1$s(共%2$d字节)%n", "J_BufferedInputStream.class", i);
            System.out.printf("不带缓存的方法需要%1$d毫秒%n", t);

            i = 0;
            d1= new Date( );
            f = new FileInputStream("J_BufferedInputStream.class");
            BufferedInputStream fb = new BufferedInputStream(f);
            while ((ch=fb.read( )) != -1){
                i++;
            }
            fb.close( );
            d2= new Date( );

            t = d2.getTime( ) - d1.getTime( );
            System.out.printf("带缓存的方法需要%1$d毫秒%n", t);
        } catch (Exception e) {
            System.err.println("发生异常:" + e);
            e.printStackTrace();
        }
    }
    
    /*运行结果:
    读取文件J_BufferedInputStream.class(共1856字节)
    不带缓存的方法需要4毫秒
    带缓存的方法需要1毫秒*/
  • 使用带缓存的时候读取的效率大大提高。

标准输入输出流的重定向

  • java.lang.System含有三个静态成员域:
    in(标准输入流,java.io.InputStream抽象类的对象),主要是接受键盘输入,System.in所指向的对象实际上是java.io.BufferedInputStream的实例对象;
    out(标准输出流,java.io.Print的对象),控制台输出;
    err(标准错误输出流,java.io.Print的对象),控制台输出;
  • 重定向即将以上三种输入输出位置进行重置
  • java.lang.System有一下三个方法进行重置为传进去的参数类型的流
public static void setIn(InputStream in);
public static void setOut(PrintStream in);
public static void setErr(InputStream err);

public static void setIn(new FireInputStream("test.txt"));将输出文件test.txt中的内容,文件必须事先存在否则抛出异常
相关标签: Java IO