天天看点

文件传输

文件(File)是最常见的数据源之一,在程序中经常需要将数据存储到文件中,例如图片文件、声音文件等数据文件。在实际使用时,文件都包含一个特定的格式,这个格式需要程序员根据需求进行设计。读取已有的文件时也需要熟悉对应的文件格式,才能把数据从文件中正确地读取出来。

在NIO类库提供之前,Java所有的文件操作分为两大类:

基于字节流的InputStream和OutputStream;

基于字符流的Reader和Writer。

通过NIO新提供的FileChannel类库可以方便地以“管道”方式对文件进行各种I/O操作,相比于传统以流的方式进行的I/O操作有了很大的变化和改进。

Java NIO中的FileChannel是一个连接到文件的通道,可以通过这个文件通道读写文件。JDK1.7之前NIO1.0的FileChannel是同步阻塞的,JDK1.7版本对NIO类库进行了升级,升级后的NIO2.0提供了异步文件通道AsynchronousFileChannel,它支持异步非阻塞文件操作(AIO)。

在使用FileChannel之前必须先打开它,FileChannel无法直接被打开,需要通过使用InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。下面示范如何通过RandomAccessFile打开FileChannel。

如果需要从FileChannel中读取数据,要申请一个ByteBuffer,将数据从FileChannel中读取到字节缓冲区中。read()方法返回的int值表示有多少字节被读到了字节缓冲区中,如果返回-1,表示读到了文件末尾。如果需要通过FileChannel向文件中写入数据,需要将数据复制或者直接存放到Byte Buffer中,然后调用FileChannel.write()方法进行写操作。

示例代码如下:

使用完FileChannel之后,需要通过close()方法关闭文件句柄,防止出现句柄泄漏。

可以通过FileChannel的position(long pos)方法设置文件的位置指针,利用该特性可以实现文件的随机读写。

在实际项目中,文件传输通常采用FTP或者HTTP附件的方式。事实上通过TCP Socket+File的方式进行文件传输也有一定的应用场景,尽管不是主流,但是掌握这种文件传输方式还是比较重要的,特别是针对两个跨主机的JVM进程之间进行持久化数据的相互交换。

具体场景如下。

(1)Netty文件服务器启动,绑定8080作为内部监听端口;

(2)在CMD控制台,通过telnet和文件服务器建立TCP连接;

(3)控制台输入需要下载的文件绝对路径;

(4)文件服务器接收到请求消息后进行合法性判断,如果文件存在,则将文件发送给CMD控制台;

(5)CMD控制台打印文件名和文件内容。