学习笔记之《Java核心技术卷II》------ 第2章 输入与输出

  • 可以从其中读入一个字节序列的对象称作输入流,可以向其中写入一个字节序列的对象称作输出流
  • 抽象类 InputStream 和 OutputStream 构成了输入/输出(I/O)类层次结构的基础
  • 面向字节的流不便于处理以 Unicode 形式存储的信息,因为 Unicode 中每个字符都使用了多个字节表示
  • read操作:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class Test{
	public static String s;
	public static void main(String[] args) throws InterruptedException, IOException{
		//test.txt内容为:hello \r\n hust
		int c = 0;
		byte[] b2 = new byte[10];
		byte[] b3 = new byte[10];
		try(
				InputStream is1 = new FileInputStream(new File("./test.txt"));
				InputStream is2 = new FileInputStream(new File("./test.txt"));
				InputStream is3 = new FileInputStream(new File("./test.txt"));) {
			while ((c = is1.read()) != -1) {
				System.out.print(c + " ");//104 101 108 108 111 13 10 104 117 115 116 
			}
			System.out.println();
			/*
			 * 以下一个while循环输出为:
			 * [104, 101, 108, 108, 111, 13, 10, 104, 117, 115]
			 * [116, 101, 108, 108, 111, 13, 10, 104, 117, 115]
			 */
			while (is2.read(b2) != -1) {//循环填充b2
				System.out.println(Arrays.toString(b2));
			}
			/*
			 * 以下一个while循环输出为:
			 * [0, 0, 0, 104, 101, 108, 108, 111, 13, 10]
			 * [0, 0, 0, 104, 117, 115, 116, 111, 13, 10]
			 */
			while (is3.read(b3, 3, 7) != -1) {//循环填充b3,注意有偏移和长度
				System.out.println(Arrays.toString(b3));
			}
		}
	}
}
  •  write 操作:(书上对于 void write(byte[] b)的解释是写出所有字节到数组b中,对此存在质疑:按着程序的结果,应该是将b写入到输出流对象中
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Test{
	public static String s;
	public static void main(String[] args) throws InterruptedException, IOException{
		int c = 104;
		byte[] b = {104,101,108,108,111,13,10,104,117,115,116};
		try(OutputStream is1 = new FileOutputStream(new File("./test_write.txt"));) {
			is1.write(c);//一次写入一个Byte
			is1.write(b);//一次性将b全写入
			is1.write(b, 3, 5);//一次性将b中从3开始,依次写入5个字节
		}
	}
}
  •  嵌套过滤器添加多重功能:
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("test.txt")));
  •  使用 PrintWriter 类的 print 方法或 println 方法向输出流对象写入数据:
try(PrintWriter pw = new PrintWriter(new File("./test_write.txt"));) {
	pw.println("hello ");
	pw.print(5);
}
  • 读入文本数据:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class Test{
	public static void main(String[] args) throws InterruptedException, IOException{
		String content = new String(Files.readAllBytes(Paths.get("test_write.txt")), "utf-8");//读取所有内容为一个 String
		List<String> list = Files.readAllLines(Paths.get("test_write.txt"));//一行行读取存入一个 List
		/*
		 * 通过调用BufferedReader对象的readLine方法依次读取每行数据
		 * 若数据读完,则返回null
		 */
		try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("test_write.txt") , StandardCharsets.UTF_8))){
			String line = "";
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
		}
	}
}
  •  DataInputStream 和 DataOutputStream :
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test{
	public static void main(String[] args) throws InterruptedException, IOException{
		try(DataOutputStream dos = new DataOutputStream(new FileOutputStream("test.txt"));){
			dos.writeInt(5);//写入一个整数
			dos.writeChars("hello");//写入一个字符串
		}
		try(DataInputStream dis = new DataInputStream(new FileInputStream("test.txt"))){
			System.out.println(dis.readInt());//读取一个整数
			System.out.println(dis.readChar());//读取一个字符
		}
	}
}
  •  RandomAccessFile :
import java.io.IOException;
import java.io.RandomAccessFile;

public class Test{
	public static void main(String[] args) throws InterruptedException, IOException{
		try(RandomAccessFile raf = new RandomAccessFile("test.txt", "rw")){
			raf.writeUTF("我");
			raf.writeChars("love");
			raf.seek(0);//将文件指针重新指至0处
			System.out.println(raf.readUTF());//读取一个UTF字符,在此用这个函数读取一个中文
			//当文件指针 == raf.length 时,文件读取结束
			while (raf.getFilePointer() < raf.length()) {
				System.out.print(raf.readChar());
			}
		}
	}
}
  • 对象输入/输出流与序列化:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test{
	public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException{
		Manager m1 = new Manager("ss", 1000);
		Manager m2 = new Manager("cc", 1100);//m1,m2的声明类型必须为Manager而不能是Employee,因为setSecretary方法只存在于Manager类中
		Employee s = new Employee("az", 500);
		m1.setSecretary(s);
		m2.setSecretary(s);
		try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test_object.txt"))){
			oos.writeObject(m1);//保存对象e1,即对对象e1进行序列化  Employee类必须实现Serializable接口,无任何方法需要实现
			oos.writeObject(m2);//保存对象e2,即对对象e2进行序列化 Employee类必须实现Serializable接口,无任何方法需要实现
		}
		Manager tmp = null;
		try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test_object.txt"))){
			Object o = ois.readObject();//按对象写入的顺序从头开始读取对象
			if(o instanceof Manager) {
				tmp = (Manager) o;
				System.out.println("manager1:" + tmp.getName() + " " + tmp.getSalary());
				Employee s1 = tmp.getSecretary();
				System.out.println("secretary:" + s1.getName() + " " + s1.getSalary());
			}
			o = ois.readObject();
			if(o instanceof Manager) {
				tmp = (Manager) o;
				System.out.println("manager2:" + tmp.getName() + " " + tmp.getSalary());
				Employee s1 = tmp.getSecretary();
				System.out.println("secretary:" + s1.getName() + " " + s1.getSalary());
			}
		}
	}
}

/*
以下为另一个文件的Employee类和Manager类
*/

import java.io.Serializable;

public class Employee implements Serializable{
	private String name;
	private int salary;
	public Employee(String name, int salary) {
		this.name = name;
		this.salary = salary;
	}
	public String getName() {
		return name;
	}
	public int getSalary() {
		return salary;
	}
}
class Manager extends Employee{
	private Employee secretary;
	public Manager(String name,int salary) {
		super(name,salary);
	}
	public void setSecretary(Employee secretary) {
		this.secretary = secretary;
	}
	public Employee getSecretary() {
		return secretary;
	}
}
  • 针对对象序列化(将对象写入文件)注意
  1. 每个对象都是用一个序列号保存 
  2. 对于遇到的每一个对象引用,该引用都会关联一个序列号
  3. 对于每个对象,当第一次遇到时,保存其对象数据到输出流中
  4. 如果某个对象之前已经被保存过,那么只做“与之前保存过的序列号为x的对象相同”的标记
  • 针对对象读取(从文件读取对象)注意
  1. 对于对象输入流中的对象,在第一次遇到其序列号时,构建它,并使用输入流中的数据来初始化它,然后记录这个顺序号和新对象之间的关联
  2. 当遇到“与之前保存过的序列号为x的对象相同”标记时,获取与这个序列号相关联的对象引用
  • 被关键字 transient 修饰的域不可被序列化
  • Path:
import java.nio.file.Path;
import java.nio.file.Paths;

public class Test{
	public static void main(String[] args) throws InterruptedException,ClassNotFoundException{
		Path path = Paths.get("E:","learningNotes","test.txt");// 对所有参数使用当前操作系统的路径分隔符进行拼接,作为path
		System.out.println(path.toAbsolutePath());// E:\learningNotes\test.txt
		System.out.println(path.getParent());// E:\learningNotes
		System.out.println(path.getFileName());// test.txt
		System.out.println(path.getRoot());// E:\
	}
}
  • 注意:路径不必对应某个实际存在的文件,它仅仅只是一个抽象的名字序列
  •  操作 Files 类读写文件:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

public class Test{
	public static void main(String[] args) throws IOException{
		Path p = Paths.get("test.txt");
		
		//读取指定路径文件的所有字节,返回为byte[]
		byte[] bytes = Files.readAllBytes(p);
		String content = new String(bytes, "utf-8");//将byte[]类型对象转成String,需提供一个charset
		System.out.println(content);
		String contentForWrite = "hello java";
		
		//按行读取并将每一行的内容保存至list,再输出list每一行
		List<String> list = Files.readAllLines(p);
		list.forEach(System.out::println);
		
		//以追加的方式将字符串contentForWrite写入p指定的文件
		Files.write(p, contentForWrite.getBytes("utf-8"),StandardOpenOption.APPEND);
		
		//以追加的方式将一个包含行的集合写入文件
		Files.write(p, list, StandardOpenOption.APPEND);
		
		//使用Files类创建输入输出流或者读入写入器
		try(
				InputStream is = Files.newInputStream(p);
				OutputStream os = Files.newOutputStream(p);
				Reader r = Files.newBufferedReader(p);
				Writer w = Files.newBufferedWriter(p)
				){
			//do something
		}
	}
}
  • 创建文件和目录:
/*
创建新目录
第一种方法需要路径中除最后一个部件外,其他部分都必须是已存在的
第二中方法将会自动创建中间未存在的目录
*/
Files.createDirectory(path);
Files.createDirectories(path);

/*
创建一个空文件。如果该文件已经存在,则以下语句就会抛出异常
*/
Files.createFile(path);
  •  复制、移动和删除文件:
//将文件从一个位置复制或移动到另一个位置。如果目标路径已经存在,那么复制或移动将失败
Files.copy(fromPath,toPath);
Files.copy(fromPath,toPath);

/*
如果想要覆盖已有的目标路径,可以使用REPLACE_EXISTING选项
如果想要所有的文件属性,可以使用COPY_ATTRIBUTES选项
*/
Files.copy(fromPath,toPath,StandardCopyOption.REPLACE_EXISTING,StandardCopyOption.COPY_ATTRIBUTES);

/*
删除文件
*/
Files.deleteIfExists(path);
  • 访问目录中的项:
//使用list方法读取目录,但是list方法不会进入子目录
try(Stream<Path> entries = Files.list(pathOfDirectory)){
    //do something
}

//使用wark方法会进入子目录,按深度优先遍历指定目录,可指定第二个参数为最大深度
try(Stream<Path> entries = Files.walk(path)){
    //do somethhing
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值