多线程复制 java_java多线程复制

package copyFileTest;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.util.concurrent.Callable;

import java.util.concurrent.CountDownLatch;

public class CopyTask implements Callable {

// 缓冲区大小

private int bufferSize = 10240;

private CountDownLatch latch;

private RandomAccessFile file = null;

private RandomAccessFile tempFile = null;

private RandomAccessFile inputFile = null;

private int id;

private long startPosition;

private long endPosition;

private long currentPosition;

public CopyTask(File file, File tmpFile, File inputFile, int id,

CountDownLatch latch, int bufferSize) {

try {

this.file = new RandomAccessFile(file, "rw");

this.tempFile = new RandomAccessFile(tmpFile, "rw");

this.inputFile = new RandomAccessFile(inputFile, "r");

} catch (FileNotFoundException e) {

e.printStackTrace();

}

this.id = id;

this.latch = latch;

this.bufferSize = bufferSize;

}

public String call() throws Exception {

try {

tempFile.seek((id - 1) * 28);

tempFile.readInt();

this.startPosition = tempFile.readLong();

this.endPosition = tempFile.readLong();

this.currentPosition = tempFile.readLong();

} catch (IOException e) {

e.printStackTrace();

}

System.out.println("Thread " + id + " begin!");

while (true) {

try {

tempFile.seek(id * 28 - 8);

if (currentPosition < endPosition) {

inputFile.seek(currentPosition);

file.seek(currentPosition);

int len = 0;

byte[] b = new byte[bufferSize];

while ((len = inputFile.read(b)) != -1) {

file.write(b, 0, len);

currentPosition += len;

tempFile.seek(id * 28 - 8);

tempFile.writeLong(currentPosition);

if (currentPosition > endPosition) {

break;

}

}

System.out.println("Thread " + id + " startPosition="

+ startPosition + ",endPosition=" + endPosition

+ ",currentPosition=" + currentPosition);

}

System.out.println("Thread " + id + " finished.");

break;

} catch (IOException e) {

e.printStackTrace();

} finally {

file.close();

tempFile.close();

inputFile.close();

}

}

latch.countDown();

return "finish";

}

}

CopyFileTest.java

package copyFileTest;

import java.io.DataOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.math.BigDecimal;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class CopyFileTest {

// 线程数

private int poolSize = 10;

// 每个线程的缓冲区大小

public int bufferSize = 10240;

private int loopSize = 10000; // 每个线程循环读的次数

/**

* 复制文件

*

* @param fileSource

* 要复制的文件

* @param fileTarget

* 要复制到的文件路径

*/

public void copy(String fileSource, String fileTarget) {

long startTime = System.currentTimeMillis();

File file = null;

File tempFile = null;

File targetFile = null;

CountDownLatch latch;

ExecutorService pool = Executors.newCachedThreadPool();

long contentLength = 0;

long threadLength = 0;

try {

new File(fileTarget).mkdirs();

file = new File(fileSource);

targetFile = new File(fileTarget + File.separator + file.getName());

tempFile = new File(fileTarget + File.separator + "_temp");

// 得到content的长度

contentLength = file.length();

poolSize = this.getPoolSize(contentLength);

System.out.println("total length=" + contentLength

+ " use ThreadSize:" + poolSize);

threadLength = loopSize * bufferSize;

if (file.exists() && tempFile.exists()) {

// 如果文件已存在,根据临时文件中记载的线程数量,继续上次的任务

int tmpFileLength = (int) tempFile.length() / 28 + 1;

latch = new CountDownLatch(tmpFileLength);

for (int i = 1; i < tmpFileLength; i++) {

pool.submit(new CopyTask(targetFile, tempFile, file, i,

latch, bufferSize));

}

} else {

// 如果下载的目标文件不存在,则创建新文件

latch = new CountDownLatch(poolSize);

targetFile.createNewFile();

tempFile.createNewFile();

DataOutputStream os = new DataOutputStream(

new FileOutputStream(tempFile));

for (int i = 0; i < this.poolSize; i++) {

os.writeInt(i + 1);

os.writeLong(i * threadLength);

if (i == this.poolSize - 1) {// 最后一个线程的结束位置应为文件末端

os.writeLong(contentLength);

} else {

os.writeLong((i + 1) * threadLength);

}

os.writeLong(i * threadLength);

pool.submit(new CopyTask(targetFile, tempFile, file, i + 1,

latch, bufferSize));

}

os.close();

}

// 等待下载任务完成

latch.await();

// 删除临时文件

System.out.println("删除临时文件" + tempFile.delete());

} catch (IOException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

pool.shutdown();

System.out.println("完成复制,所用时:"

+ (System.currentTimeMillis() - startTime));

}

}

/**

* 根据总大小 缓存区与每个线程默认循环次数,判断用几个线程

*

* @param contentLength

* @return

*

*/

public int getPoolSize(long contentLength) {

int poolSize = 1;

BigDecimal contentBig = new BigDecimal(contentLength);

BigDecimal bufferBig = new BigDecimal(bufferSize);

BigDecimal loopBig = new BigDecimal(loopSize);

poolSize = contentBig.divide(bufferBig.multiply(loopBig), 0,

BigDecimal.ROUND_HALF_UP).intValue();

return poolSize;

}

public static void main(String[] args) {

String fileSource = "D:\\add.rar"; // 要复制的文件

String fileTarget = "D:\\copyTest";

new CopyFileTest().copy(fileSource, fileTarget);

}

}

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2011-07-01 11:26

浏览 1256

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中进行 Socket 通信时,我们可以使用多线程来实现同时与多个客户端进行通信。这种方式可以提高服务器的并发处理能力。 具体实现方法是,服务器端使用一个主线程监听客户端的连接请求,当有新的连接请求时,主线程创建一个新的线程来处理该客户端的请求。这样,每个客户端的请求都会在一个单独的线程中进行处理,互不影响。 以下是一个简单的 Java Socket 多线程服务器端代码示例: ```java import java.net.*; import java.io.*; public class MultiThreadServer implements Runnable { private Socket clientSocket; public MultiThreadServer(Socket clientSocket) { this.clientSocket = clientSocket; } public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8080); System.out.println("Server started"); while (true) { Socket clientSocket = serverSocket.accept(); System.out.println("Accepted connection from " + clientSocket); new Thread(new MultiThreadServer(clientSocket)).start(); } } public void run() { try { PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("Received message: " + inputLine); out.println("Message received: " + inputLine); } in.close(); out.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 在上面的代码中,我们创建了一个 MultiThreadServer 类来处理客户端请求。在 main 方法中,我们首先创建了一个 ServerSocket 并在端口 8080 上监听客户端连接请求。当有新的连接请求时,我们创建一个新的 MultiThreadServer 线程来处理该客户端的请求。 在 MultiThreadServer 类中,我们实现了 Runnable 接口,并重写了 run 方法。在 run 方法中,我们使用 BufferedReader 和 PrintWriter 来读取和发送消息。注意,在处理完一个客户端请求后,我们需要关闭连接。 以上就是一个简单的 Java Socket 多线程服务器端代码示例。通过这种方式,我们可以轻松实现高并发的 Socket 通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值