java断点续传javaee_JavaEE - 13IO流2

JavaEE - 13IO流2

(7)处理流之四: 打印流

实现将基本数据类型的数据格式转化为字符串输出

打印流: PrintStream 和 PrintWriter

提供了一系列重载的print()和println()方法,用于多种数据类型的输出

PrintStream和PrintWriter的输出不会抛出 IOException 异常。

PrintStream和PrintWriter有自动flush 功能

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

System.out返回的是PrintStream的实例。

@Testpublic voidtest2(){

PrintStream ps= null;try{

FileOutputStream fos= new FileOutputStream(new File("tee.txt"));//创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新输出缓冲区)

ps = new PrintStream(fos, true);if(ps != null){

System.setOut(ps);

}for(int i =0; i<=255; i++){

System.out.print((char)i); //输出ASCII字符

if(i % 50 == 0){ //每50个数据一行

System.out.println();

}

}

}catch(FileNotFoundException e) {

e.printStackTrace();

}finally{if(ps != null){

ps.close();

}

}

}

(8)处理流之五:数据流

为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。

数据流有两个类:(用于读取和写出基本数据类型、String类型的数据)

DataInputStream 和 DataOutputStream

分别"套接"在 InputStrean 和 OutputStream 子类的流上

DataInputStream中的方法

boolean readBoolean()/ char readChar()/ String readUTF()/ void readFully(byte[] b)

byte readByte()/ short readShort()/ int readInt()/ long readLong()/ float readFloat()/ double readDouble()

DataOutputStream中的方法

将上述的方法的read改成相应的write即可。

将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中。

注意点: 读取不同类型的数据的顺序要与写入文件时保存的顺序一致。

@Testpublic void test2() throwsIOException {

DataOutputStream dos= new DataOutputStream(new FileOutputStream("hello4.txt"));

dos.writeUTF("孙悟空");

dos.flush();

dos.writeInt(23);

dos.flush();

dos.writeBoolean(true);

dos.flush();

dos.close();

DataInputStream dis= new DataInputStream(new FileInputStream("hello4.txt"));

String name=dis.readUTF();int age =dis.readInt();boolean isMale =dis.readBoolean();

System.out.println("name:" + name +",age: " + age +",isMale: "+ isMale); //name:孙悟空,age: 23,isMale: true

}

(9)处理流之六:对象流

ObjectInputStream 和 ObjectOutputStream

用于存储和读取基本数据类型数据或对象的处理流。

强大之处是可以把Java中的对象写入到数据库中,也能把对象从数据源中还原回来。

序列化:  用 ObjectOutputStream类保存 基本数据类型 数据或对象的机制

反序列化: 用 ObjectInputStream类读取 基本数据类型 数据或对象的机制

ObjectOutputStream和ObjectInputStream 不能序列化 static 和 transient 修饰的成员变量

(9.1)对象的序列化

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,

从而允许把这种二进制流持久地保存在磁盘上,或通过网络将二进制流传输到另一个网络节点。

当其它程序获取了这种二进制流,可以恢复成原来的Java对象。

序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原

序列化是RMI(Remote Method Invoke - 远程方法调用)过程的参数和返回值都必须实现的机制,

而RMI是JavaEE的基础。因此序列化机制是JavaEE平台的基础。

如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的。

为了让某个类是可序列化的,该类必须实现以下两个接口之一。否则会抛出NotSerializableException异常。

Serializable /  Externalizable

凡是实现Serializable 接口的类都有一个表示序列化版本标识符的静态变量:

private static final long serialVersionUID = 8537212141160296410L;

serialVersionUID用来表明类的不同版本间的兼容性。其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。

如果没有显式定义静态变量,它的值是Java运行时环境根据类的内部细节自动生成的,若类的实例变量做了修改,serialVersionUID可能发生变化。

Java序列化机制是通过运行时判断类的serialVersionUID来验证版本一致性的。

在进行反序列化时,JVM会把传来的字节流中serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化。

否则就会出现序列化版本不一致的异常。(InvalidCastException)。

示例: Person类 序列化的要求:

实现Serializable接口

提供全局常量serialVersionUID

Person内部所有属性都必须是可序列化的。(默认情况下,基本数据类型可序列化)

@Testpublic void test3() throwsIOException, ClassNotFoundException {

ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("hello5.txt"));

oos.writeObject(new String("天安门"));

oos.flush();

oos.close();

ObjectInputStream ois= new ObjectInputStream(new FileInputStream("hello5.txt"));

Object obj=ois.readObject();

String s=(String) obj;

System.out.println(s);//天安门

}

public class Person implementsSerializable {private static final long serialVersionUID = -5015176660385488112L;privateString name;private intage;privatePet pet;//省略其他代码

}

@Testpublic void test3() throwsIOException, ClassNotFoundException {

ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("hello5.txt"));

oos.writeObject(new String("天安门"));//java.io.NotSerializableException: Person java.io.NotSerializableException: Pet

oos.writeObject(new Person("Tom",23, new Pet("猫猫")));

oos.flush();

oos.close();

ObjectInputStream ois= new ObjectInputStream(new FileInputStream("hello5.txt"));

Object obj=ois.readObject();

String s=(String) obj;

System.out.println(s);//天安门

Object obj2 =ois.readObject();

Person person=(Person) obj2;

System.out.println(person);

}

(10)随机存取文件流

RandomAccessFile声明在java.io包下,但直接继承于java.lang.Object类。

并且它实现了DataInput、DataOutput这两个接口,意味着这个类可以读也可以写。

RandomAccessFile类支持"随机访问"的方法,程序可以直接跳到文件的任意地方来读、写文件。

支持只访问文件的部分内容

可以向已存在的文件后追加内容

RandomAccessFile对象包含一个记录指针,用以标示当前读写处的位置。对象可以自由移动记录指针:

long getFilePointer():  获得文件记录指针的当前位置。

long seek(long pos):    将文件记录指针定位到pos位置。

构造器

public RandomAccessFile(File file, String mode)

public RandomAccessFile(String file, String mode)

创建RandomAccessFile 类实例需要指定一个mode参数,该参数指定RandomAccessFile的访问模式:

r:   以只读方式打开

rw:  打开以便读取和写入

rwd: 打开以便读取和写入; 同步文件内容的更新

rws: 打开以便读取和写入; 同步文件内容和元数据的更新

如果模式为只读r,则不会创建文件,而是去读取一个已经存在的文件,如果不存在会出现异常。

如果模式为rw读写,如果文件不存在则会去创建文件,如果存在则不会创建。

@Testpublic void test4() throwsIOException {

RandomAccessFile raf1= new RandomAccessFile(new File("桌面壁纸.jpg"),"r");

RandomAccessFile raf2= new RandomAccessFile(new File("桌面壁纸2.jpg"),"rw");byte[] bytes = new byte[1024];intlen;while((len = raf1.read(bytes)) != -1){

raf2.write(bytes,0,len);

}

}

seek()方法

@Testpublic void test5() throwsIOException {

RandomAccessFile raf1= new RandomAccessFile(new File("hello.txt"),"rw");

raf1.seek(3);

raf1.write("xyz".getBytes()); //123456789 --> 123xyz789

raf1.close();

}

@Testpublic void test6() throwsIOException {

RandomAccessFile raf1= new RandomAccessFile(new File("hello.txt"),"rw");

raf1.seek(3);

StringBuilder stringBuilder= new StringBuilder((int)new File("hello.txt").length());byte[] buffer = new byte[20];intlen;while((len = raf1.read(buffer)) != -1){

stringBuilder.append(new String(buffer,0,len));

}

System.out.println(stringBuilder);

FileInputStream fis= new FileInputStream(new File("hello.txt"));

BufferedReader reader= new BufferedReader(new InputStreamReader(fis));char[] buffer2 = new char[10];intlen2;

String str2= "";while((len2 = reader.read(buffer2)) != -1){

str2+= new String(buffer2,0, len2);

}

System.out.println(str2);

ByteArrayOutputStream baos= new ByteArrayOutputStream();byte[] buffer3 = new byte[10];intlen3;while((len3 = fis.read(buffer3)) != -1){

baos.write(buffer3,0,len3);

}

System.out.println(baos.toString());

}

断点续传:

使用RandomAccessFile这个类,来实现一个多线程断点下载的功能。

下载前建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,

每次暂停时,保存上一次的指针,断点下载时,从上一次的地方下载,实现断点下载或上传的功能。

(11)NIO.2中Path、Paths、Files类的使用

(11.1)Java NIO概述

Java NIO(New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以代替标准的Java IO API。

NIO与原来的IO有同样的作用和目的,但使用的方法完全不同。

NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。 NIO以更加高效的方式进行文件的读写操作。

Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套是网络编程NIO。

java.nio.channels.Channel

FileChannel:         处理本地文件

SocketChannel:       TCP网络编程的客户端的Channel

ServerSocketChannel: TCP网络编程的服务器端的Channel

DatagramChannel:     UDP网络编程中发送端和接收端的Channel

(11.2)NIO.2 中 Path、Paths、Files类

随着JDK 7的发布,Java 对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,称为NIO.2。

早期Java只提供了一个File类来访问文件系统,但File类功能比较有限,提供的方法性能也不高。

大多数方法在出错时仅返回失败,并不会提供异常信息。

NIO.2为了弥补不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。

Path可以看成是File类的升级版本,实际引用的资源也可以不存在。

import java.io.File; File file = new File("index.html");

import java.nio.file.Paht; import java.nio.file.Paths; Path path = Paths.get("index.html");

NIO.2 在java.nio.file包下提供了Files、Paths工具类,

Files包含了大量静态的工具方法来操作文件;Paths包含了两个返回Path的静态工厂方法。

Paths类提供的静态get()方法来获取Path对象:

static Path get(String first, String... more): 用来将多个字符串串连成路径

static Path get(URI uri): 返回指定uri对应的Path路径

org.apache.commons.io.FileUtils

(11.3)Path接口

Path常用方法

String toString():               返回调用Path对象的字符串表示形式

boolean startsWith(String path): 判断是否以path路径开始

boolean endsWith(String path):   判断是否以path路径结束

boolean isAbsolute():            判断是否是绝对路径

Path getParent():                返回Path对象包含整个路径,不包含Path对象指定的文件路径

Path getRoot():                  返回调用Path对象的根路径

Path getFileName():              返回与调用Path对象关联的文件名

int getName(int idx):            返回指定索引位置idx的路径名称

Path toAbsolutePath():           作为绝对路径返回调用Path对象

Path resolve(Path p):            合并两个路径,返回合并后的路径对应的Path对象

File toFile():                   将Path转化为File类的对象

(11.4)File类的方法

java.nio.file.Files 用于操作文件或目录的工具类

Files常用方法:

Path copy(Path src, Path dest, CopyOption ... how):        文件的复制

Path createDirectory(Path path, FileAttribute>... attr): 创建一个目录

Path createFile(Path path, FileAttribute>... atrr):      创建一个文件

void deleteIfExists(Path path):     删除一个文件/目录,如果不存在,执行报错

void deleteIfExists(Path path):     Path对应的文件/目录如果存在,执行删除

Path move(Path src, Path dest, CopyOption... how): 将src 移动到dest位置

long size(Path path):                            返回path 指定文件的大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值