视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Java网络编程-Socket-文件传输小案例
2025-10-04 09:03:04 责编:小OO
文档
Java网络编程-Socket-文件传输小案例

package com.kum.im.file;

import java.nio.channels.SocketChannel;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.ByteBuffer;

import java.io.RandomAccessFile;

import java.io.FileOutputStream;

import java.io.File;

import java.io.IOException;

import java.nio.channels.ClosedChannelException;

/**

*

Title: Socekt编程学习

*

*

Description: 文件传输接收端

*

*

Copyright: Copyright (c) 2009

*

*

Company: 酷猫科技

*

* @author 贺翔<380595305@qq.com>

* @version 1.0

*/

public class ReveiceThread extends Thread {

private FileUtil util = new FileUtil();

private SocketChannel r_channel = null;

private ByteBuffer buf = ByteBuffer.allocate(util.getBlockSize() + 9);

public ReveiceThread(SocketChannel channel) throws Exception {

this.r_channel = channel;

this.r_channel.configureBlocking(false);

}

public void run() {

try {

Selector selector = Selector.open();

SelectionKey key = r_channel.register(selector, SelectionKey.OP_READ);

buf.clear();

File file = null;

FileOutputStream fout = null;//文件输出流对象

RandomAccessFile raf = null;//创建临时文件对象

int FileSize = 0; //文件大小

String FileName = ""; //文件名称

int BlockIndex = 0; //文件块索引号

int BlockSize = 0; //文件块大小

int readlen = 0; //读到的数据长度

int buflen = 0; //buf的长度

byte cmd = 0x0; //命令码

int BlockNum = 0; // 文件块数据计数器

int CompSize = 0; //已经完成数

while (key.selector().isOpen()) {

int selkey = selector.select();

if (selkey == 0) {

readlen = this.r_channel.read(buf); //开始读数据

buflen += readlen; //记录缓冲区buf的长度

if (readlen >= 1) { //读到了数据

buf.rewind(); ///数据指针指到0

cmd = buf.get(); //读取一个字节,获得文件头信息,判断发送信息类型(head or body)

switch (cmd) {

case 0x1: { ///文件信息

if (buflen >= 260) {

FileSize = buf.getInt(); //获取文件大小

byte[] filename = new byte[255];

buf.get(filename); //从缓冲区中读取255个字节,获取文件名

FileName = (new String(filename)).trim();

buf.compact(); //删除读取过的数据

buflen -= 260; //缓冲区大小减去已读的260个字节大小

buf.position(buflen); //数据指针指向buf的最后位置

System.out.println("文件名-->:" + FileName +

2: { //文件主体数据(body)

if (buflen >= 9) {

BlockIndex = buf.getInt(); //获得文件块索引号

BlockSize = buf.getInt(); //获得文件块大小

if (buflen >= (9 + BlockSize)) { //缓冲区大小减去已读数据

byte[] blockdb = new byte[BlockSize];

buf.get(blockdb); //读取文件块数据

buf.compact(); //删除已读数据

buflen -= (9 + BlockSize);

buf.position(buflen); //数据指针指向buf缓冲区最后位置

if (BlockSize < util.getBlockSize()) {

//如果收到的数据块大小小于定义的最大文件块大小

byte[] tmpdb = new byte[util.getBlockSize()]; ///定义临时最大数据块

System.arraycopy(blockdb, 0, tmpdb, 0, BlockSize);//

raf.seek( (util.getBlockSize() + 4) * BlockIndex); //(+4)是用于存放文件大小信息的

//文件块写入临时文件中将相应数据块放到相应的位置中去

raf.writeInt(BlockSize); //向临时数据块中写入文件大小信息

raf.write(tmpdb); //向临时数据块中写入文件块信息

BlockNum++; //文件块计数器累加

}

else {

//收到的数据等于文件块定义的最大值

raf.seek( (util.getBlockSize() + 4) * BlockIndex);

//文件块写入临时文件中将相应数据块放到相应的位置中去

raf.writeInt(BlockSize);

raf.write(blockdb);

BlockNum++;//文件块计数器累加

}

System.out.println("写入临时文件完成: ---->" +

(CompSize += BlockSize) + "****");

FileSize -= BlockSize; ///每收到一块,就从总文件大小里减去

if (FileSize == 0) { ///如果减到0了,说明文件块已经收全了,可以关闭文件了。

for (int i = 0; i < BlockNum; i++) {

//根据文件块个数循环将临时文件写入正式文件

raf.seek( (util.getBlockSize() + 4) * i);

BlockSize = raf.readInt();//从临时文件中读取文件块大小

byte[] tmpdb = new byte[BlockSize];

raf.read(tmpdb);//从临时文件中读取文件块数据

fout.write(tmpdb);//向正式文件中写入文件块

}

raf.close();//释放资源

file.delete(); ///删除临时文件

fout.close();

System.out.println("*******文件已经接收完成了!*******");

}

}

else {

buf.position(buflen); ///数据指针指向buf的最后位置

}

}

else {

buf.position(buflen); ///数据指针指向buf的最后位置

}

}

break;

}

}

}

}

}

catch (ClosedChannelException ex) {

System.out.println("发生ClosedChannelException异常,原因 ----> :" + ex.getMessage());

}

catch (IOException ex) {

System.out.println("打开选择器时异常,原因 ----> :" + ex.getMessage());

}

}

}下载本文

显示全文
专题