搞定Java中I/O输入输出&重定向

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搞定Java中I/O输入输出&重定向相关的知识,希望对你有一定的参考价值。

FileReader

阅读字符文件的便利类。
该类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。
要自己指定这些值,请在FileInputStream上构造一个InputStreamReader。
FileReader用于读取字符流。
要读取原始字节流,请考虑使用FileInputStream。

package IO;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReader_Test {
	public static void main(String[] args) throws IOException {
		// 创建FileReader对象,方法参数里绑定 文件源,对象指向文件的位置
		FileReader abc=new FileReader("D:\\\\帅\\\\zhu.txt");
		// 调用read方法读取文件
//		int len=0;//返回字符长度
//		while((len=abc.read())!=-1) {
//			System.out.println((char)len); // 将字节转化为字符
//		}
		char x[]=new char[1024];//创建一个1024大小的字节数组存取读到的字符
		int length=0;//表示每次读取有效字符的个数
		while((length=abc.read(x))!=-1) {
			System.out.println(new String(x,0,length));//读取数组中的部分,
		}
		// 释放资源,流使用会占用内存,使用完毕把内存清空,提高程序的效率
		abc.close();
	}
}

FileInputStream

FileInputStream从文件系统中的文件获取输入字节。 什么文件可用取决于主机环境。

package IO;
// JVM-->OS
// 方法参数的byte[]作用是:
// 起缓冲作用,存储每次读到的字节,数组长度一般为1024或倍数
// 返回值int是有效字节个数
// (new Stringbyte[],0,byte.length):只输出有效的字节
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

// FileInputSteam字节输入流,是所有输入类的超类
// 构造方法中:String name是文件路径,File是文件

public class FileInputStream_Test {
	public static void main(String[] args) throws IOException {
		// 作用:创建对象,并把对象指向,构造方法中传递的文件路径
		FileInputStream file=new FileInputStream("D:\\\\帅\\\\zhu.txt");
		// 使用read方法读取,读取的是字节,读完返回-1;
//		int x=0;
//		while((x=file.read())!=-1) {
//			System.out.println((char)x);
//		}
//		// 释放资源,流使用会占用内存,使用完毕把内存清空,提高程序的效率
//		file.close();
		// 一次读取多个文件
		byte c[]=new byte[3];
		int d = file.read(c);  // 读取一定数量的字节,并将其存在缓冲区数组c中
		System.out.println(d);
		System.out.println(new String(c));
	}
}

PrintStream

PrintStream将功能添加到另一个输出流,即能够方便地打印各种数据值的表示。 还提供了另外两个功能。
不像其他输出流,一个PrintStream从不抛出一个IOException ; 相反,异常情况只是设置一个可以通过checkError方法测试的内部标志。
可选地,可以创建PrintStream以便自动刷新; 这意味着flush方法在写入字节数组之后自动调用,其中一个println方法被调用,或换行字符( ‘\\n’ )被写入。

使用平台的默认字符编码将PrintStream打印的所有字符转换为字节。 PrintWriter类应该在需要写入字符而不是字节的情况下使用。

package IO;

import java.io.IOException;
import java.io.PrintStream;

public class PrintStream_Test {
	public static void main(String[] args) throws IOException {
		// 创建打印流输出对象,构造方法中传递文件目的地
		PrintStream print=new PrintStream("D:\\\\yangliu.txt");
		// 使用父类方法write写数据
		print.write(97);
		// 使用自己方法
		print.print("shuai");
		// 以上在控制台打印
		// 使用System.setout打印指定位置:"D:\\\\yangliu.txt"
		System.setOut(print);
		// 释放资源
		print.close();
	}
}

OutputStreamWriter

OutputStreamWriter是从字符流字节流的桥梁:使用指定的charset将写入的字符编码为字节。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
每次调用write()方法都会使编码转换器在给定的字符上被调用。 所得到的字节在写入底层输出流之前累积在缓冲区中。 请注意,传递给write() 方法的字符不会缓冲。

为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用。
例如:

Writer out = new BufferedWriter(new OutputStreamWriter(System.out));

代理对是由两个char值的序列表示的字符:“\\ uD800”到“\\ uDBFF”范围内的高代理,后跟“\\ uDC00”到“\\uDFFF”范围内的低代理。

一个畸形的替代元素是一个高替代品,其后没有高替代品的低替代品或低替代品。

这个类总是用字符集的默认替换序列替换格式不正确的代理元素和不可映射的字符序列 。
当需要更多的编码过程控制时,应使用CharsetEncoder类。

测试代码:

// GBK一个字符2字节,utf-8一个字符3字节
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriter_Test {
	public static void main(String[] args) throws IOException, FileNotFoundException {
		// 创建一个OutputStreamWriter对象,构造方法中传递字节输出流和指定编码表
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("D:\\\\shuai.txt",true), "GBK");
		// 使用write,把字符转化为字节 存储到缓冲区中
		osw.write("帅爱柳");
		// 使用flush方法,把内存缓冲区的字节刷新到文件夹中(使用字节流写数据的过程
		osw.flush();
		// 释放资源
		osw.close();
	}
}

ObjectOutputStream

将实例写入文件中,序列化与反序列化。

实例类需要实现 Serializable接口。

private static final long serialVersionUID=11L定义一个 序列号,不会发生序列化冲入异常

package IO;
// private static final long serialVersionUID=11L定义一个 序列号,不会发生序列化冲入异常
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

// ObjectOutputStream:对象的序列化流
public class ObjectOutputStream_Test {
	public static void main(String[] args) throws IOException{
		// 创建ObjectOutputStream对象,构造方法中传递字节输出流
		ObjectOutputStream obj=new ObjectOutputStream(new FileOutputStream("D:\\\\yangliu.txt",true));
		obj.writeObject(new Person("帅",18));
	}
}
class Person implements Serializable{ // Serializable进行序列化标记,
	String name;
	int age;
	
	public Person() {
		super();
	}
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Alearn.Person [name=" + name + ", age=" + age + "]";
	}
}

把集合对象写入文件中

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class Output_Test {
	public static void main(String[] args) throws IOException, IOException, ClassNotFoundException {
		// 定义一个存储Person类的集合
		ArrayList<Person> list=new ArrayList<>();
		// 往list中添加对象
		// list.add(new Alearn.Person("帅",18);
		// 创建一个序列化输出流OutputStream对象
		ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("D:\\\\yangliu.txt", true));
		// 还用write方法把集合写入
		o.writeObject(list);
		// 创建一个反序列化输入流InputStream对象
		ObjectInputStream obj = new ObjectInputStream(new FileInputStream("D:\\\\yangliu.txt"));
		// 使用readObject类进行读,返回是Object
		Object x=obj.readObject();
		// 把x强转化为ArrayList集合
		ArrayList<Person> list2=(ArrayList<Person>)x;
		// 对集合进行遍历
		for(Person p:list2) {
			System.out.println(p);
		}
		// 释放资源
		obj.close();
		o.close();
	}
}

重定向 (Redirect)

Java的标准输入/输出分别通过System.inSystem.out来代表,在默认的情况下分别代表键盘和显示器,当程序通过System.in来获得输入时,实际上是通过键盘获得输入。当程序通过System.out执行输出时,程序总是输出到屏幕。

System类中提供了三个重定向标准输入/输出的方法:

static void setErr(PrintStream err) 重定向“标准”错误输出流

static void setIn(InputStream in) 重定向“标准”输入流

static void setOut(PrintStream out)重定向“标准”输出流

补充拓展

System类包含几个有用的类字段和方法。 它不能被实例化。
System类提供的设施包括标准输入,标准输出和错误输出流;
访问外部定义的属性和环境变量; 一种加载文件和库的方法; 以及用于快速复制阵列的一部分的实用方法。

下面程序通过重定向标准输出流,将System.out的输出重定向到文件输出,而不是在屏幕上输出。

import java.io.FileOutputStream;
import java.io.PrintStream;
public class Test {
	public static void main(String[] args) throws Exception {
		PrintStream ps = new PrintStream(new FileOutputStream("work"));
		System.setOut(ps);
		System.out.println("Hello World!");
 
	}
}

下面的代码将System.in重定向到文件输入,所以将不接受键盘输入。

import java.io.FileInputStream;
import java.util.Scanner;
 
 
public class Test {
	public static void main(String[] args) throws Exception {
		FileInputStream fis=new FileInputStream("work");
		System.setIn(fis);
		
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextLine()) {
			System.out.println(sc.nextLine());
		}
	}
}

将两个txt文件内容互传

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;
 
public class Demo1 {
	public static void main(String[] args) throws FileNotFoundException {
        /**
         * 保存最原始的输入输出流
         */
        InputStream in = System.in;
        PrintStream out = System.out;
        /**
         * 将标准输入流重定向至 in.txt
         */
        System.setIn(new FileInputStream("d:\\\\test\\\\in.txt"));
        
        Scanner scanner = new Scanner(System.in);
        /**
         * 将标准输出流重定向至 out.txt
         */
        System.setOut(new PrintStream("d:\\\\test\\\\out.txt"));
        /**
         * 将 in.txt中的数据输出到 out.txt中
         */
        while (sc.hasNextLine()) {
            String str = scanner.nextLine();
            System.out.println(str);
        }
        /**
         * 将标准输出流重定向至控制台
         */
        System.setIn(in);
        /**
         * 将标准输出流重定向至控制台
         */
        System.setOut(out);
        scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        System.out.println("输入输出流已经恢复 " + string);
    }
}

第二种方式:

package IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;

//Java标准输入是 System.in, 代表键盘
//标准输出是 System.out, 代表显示器。
//System类提供下面重定向标准IO。
//setErr(PrintStream err): 重定向标准错误
//setIn(InputStream in): 重定向标准输入
//setOut(PrintStream out): 重定向标准输出

public class redirect {
    public static void main(String[] args) {
        try {
            FileInputStream file = new FileInputStream("D://zhuu.txt");
            PrintStream ps = new PrintStream("D://shuai.txt");
            System.setIn(file);
            System.setOut(ps);
            Scanner sc = new Scanner(System.in);
            sc.useDelimiter("\\n");  // 设定标记符 \\n
            while (sc.hasNext()) {
                System.out.println(sc.next());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

参考博客
Link
Link

感谢

以上是关于搞定Java中I/O输入输出&重定向的主要内容,如果未能解决你的问题,请参考以下文章

25 Java学习之标准I/O流重定向

10标准I/O输入输出重定向及管道

标准 I/O 和管道

标准I/O重定向和管道

标准I/o重定向和管道

I/O重定向