字节流的文件拷贝操作如下; (字符流也一样)
public static void main(String[] args) {
File file = new File("src\\io流2\\File\\1.txt");
File file2 = new File("src\\io流2\\File\\3.txt");
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(file2);
int len = -1;
byte[] chars = new byte[10];
while ((len = fileInputStream.read(chars)) > 0){
fileOutputStream.write(chars,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileOutputStream != null){
try {
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
if (fileInputStream != null){
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
当读取图片,视频等二进制文件时最好使用字节流来读取,如果使用字符流读取,每次读取多个字节,可能会出现丢失的情况。
节点流的功能都比较单一,性能较低。处理流,也称之为包装流,相对于节点流更高级,这里存在一个设计模式——装饰设计模式。
new 流类A( new 流类B(..) ) ;
需求:演示缓冲流读取二进制文件(图片,音频…)
public static void main(String[] args) throws IOException {
/* 需求:演示字节缓冲流(BufferedInputStream-BufferedOutputStream)-输入操作和输出操作
作业目的:掌握字节缓冲流(BufferedInputStream-BufferedOutputStream)-输入操作和输出操作*/
File file = new File("src\\io流2\\File\\1.png");
File file2 = new File("src\\io流2\\File\\2.png");
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file2));
int len = -1;
byte[] c = new byte[1024];
while ((len = bufferedInputStream.read(c)) > 0){
bufferedOutputStream.write(c,0,len);
}
bufferedOutputStream.close();
bufferedInputStream.close();
}
序列化:指把Java堆内存中的对象数据,通过某种方式把对象数据存储到磁盘文件中或者传递给给网络上传输。序列化在分布式系统在应用非常广泛。
反序列化:把磁盘文件中的对象的数据或者把网络节点上的对象数据恢复成Java对象的过程。
需要做序列化的类必须实现序列化接口:java.io.Serializable(这是标志接口[没有抽象方法])
可以通过IO中的对象流来做序列化和反序列化操作。
ObjectOutputStream:通过writeObject方法做序列化操作的
ObjectInputStream:通过readObject方法做反序列化操作的
如果字段使用transient 修饰则不会被序列化。
class User implements Serializable {
private String name;
private transient String password;
private int age;
public User(String name, String password, int age) {
this.name = name;
this.password = password;
this.age = age;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public int getAge() {
return age;
}
public String toString() {
return "User [name=" + name + ", password=" + password + ", age=" + age + "]";
测试代码
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化操作
File file = new File("src\\io流2\\File\\user.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
User user = new User("小狼","xaidf",18);
objectOutputStream.writeObject(user);
objectOutputStream.close();
//反序列化操作
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
User user1 = (User) objectInputStream.readObject();
System.out.println(user1);
objectInputStream.close();
}
序列化的版本问题
当类实现Serializable接口后,在编译的时候就会根据字段生成一个缺省的serialVersionUID值,并在序列化操作时,写到序列化数据文件中。
但随着项目的升级系统的class文件也会升级**(增加一个字段/删除一个字段**),此时再重新编译,对象的serialVersionUID值又会改变。那么在反序列化时,JVM会把对象数据数据中的serialVersionUID与本地字节码中的serialVersionUID进行比较,如果值不相同(意味着类的版本不同),那么报异常InvalidClassException,即:类版本不对应,不能进行反序列化。如果版本号相同,则可以进行反序列化。
打印流是一种特殊是输出流,可以输出任意类型的数据,比一般的输出流更好用。可以作为处理流包装一个平台的节点流使用,平时我们使用的System.out.println其实就是使用的打印流。
PrintStream :字节打印流
PrintWriter :字符打印流
打印流中的方法:
提供了print方法:打印不换行
提供了println方法:先打印,再换行
private static void test5() throws Exception {
//1):创建源或者目标对象
File dest = new File("file/result3.txt");
//2):创建IO流对象
PrintStream ps = new PrintStream(new FileOutputStream(dest));
//3):具体的IO操作
ps.println("Will");
ps.println(17);
ps.println("众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。");
//4):关闭资源(勿忘),打印流可以不用关闭
}
标准IO
标准的输入:通过键盘录入数据给程序
标准的输出:在屏幕上显示程序数据
在System类中有两个常量int和out分别就表示了标准流:
InputStream in = System.in;
PrintStream out = System.out;
需求:做一个ECHO(回声)的小案例
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in); //接受用户输入数据后敲回车
while (sc.hasNextLine()) { //判断用户是否输入一行数据
String line = sc.nextLine(); //获取用户输入的数据
System.out.println("ECHO:" + line);//显示用户输入的数据
}
}