图片的多线程处理
public class PhotoHandle {
public static void main(String[] args) {
File file = new File("D:\\photo.bmp");
photoHandle(file, 4);//把文件分成4个线程来处理
}
public static void photoHandle(File file, int threadNumber) {
long length = file.length();
long unitLength = length/threadNumber;//把图片长度按线程数等分
for(int i=0; i<threadNumber; i++){
long begin = 54;//图片一开始都不从零开始的
long end = length;
if (i != 0){
begin = unitLength*i;
}
if(i!=threadNumber-1){
end = unitLength*(i+1)-1;
}
String name = "线程"+i;
MyThread myThreads = new MyThread(name, file, begin, end);
new Thread(myThreads).start();
System.out.println(name + "已开启");
}
}
}
==================MyThread类=======================
public class MyThread implements Runnable {
private String name;//线程名
private File file;//文件名
private long begin;//起始位置
private long end;//读取的结束位置
public MyThread(String name, File file, long begin, long end) {
this.name = name;
this.file = file;
this.begin = begin;
this.end = end;
}
@Override
public void run() {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "rw");
raf.seek(begin);// raf指针定位到最开始
while (begin <= end) {//还没到最后,则继续
int i = 255 - raf.read();
raf.seek(raf.getFilePointer() - 1);// 或raf.seek(begin)
raf.write(i);
begin++;
}
System.out.println(name + "拷贝完成!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
IOUtils.closeRandomAccessFile(raf);
}
}
}
多线程分段示意图如下
此图同样适用于下例的文件拷贝
(大)文件的的多线程拷贝
public class MultiThreadCopy{
public static void main(String[] args) {
File sourceFile = new File("E:\\javaIO\\myeclipse.exe");//源文件地址
File targetDir = new File("e:/javaFile");//目标文件地址
int threadNumber = 4;
copyFile(sourceFile, targetDir, threadNumber);
}
public static void copyFile(File sourceFile, File targetDir, int threadNumber) {
// TODO Auto-generated method stub
if(!targetDir.exists()){
targetDir.mkdirs();
}
File targetFile = new File(targetDir, sourceFile.getName());
long length = sourceFile.length();
long unitLength = length/threadNumber;
for(int i=0; i<threadNumber; i++){
long begin = 0;
long end = length;
if(i!=0){
begin = unitLength*i;
}
if(i!=threadNumber-1){
end = unitLength*(i+1)-1;
}
String name = "线程"+i;
new MyThread(name, sourceFile, targetFile, begin, end).start();
System.out.println(name+"启动完成!");
}
}
}
==================MyThread类=======================
public class MyThread extends Thread{
private String name;
private File sourceFile;
private File targetDir;
private long begin;
private long end;
public MyThread(String name, File sourceFile, File targetDir, long begin, long end) {
this.name = name;
this.sourceFile = sourceFile;
this.targetDir = targetDir;
this.begin = begin;
this.end = end;
}
@Override
public void run() {
//定义读写的文件访问流
RandomAccessFile rafRead = null;
RandomAccessFile rafWrite = null;
try {
rafRead = new RandomAccessFile(sourceFile, "r");
rafWrite = new RandomAccessFile(targetDir, "rw");
//设置文件指针的开始位置和文件长度
rafWrite.setLength(end);
rafRead.seek(begin);
rafWrite.seek(begin);
int buffSize = 1024*6;
byte[] buff = new byte[buffSize];
while((begin+buffSize)<=end){
//把数据读入到buff缓冲数组中
rafRead.read(buff);
//把buff缓冲数组的数据写入到目标文件
rafWrite.write(buff);
//起始位置再向前移
begin+=buffSize;
}
//begin+buffSize超出了每一段的结尾,最后那一撮另外读
long lastSize = end-begin;
rafRead.read(buff, 0, (int) lastSize);
rafWrite.write(buff, 0, (int) lastSize);
System.out.println(this.name+"拷贝完成!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
IOUtils.closeRandomAccessFile(rafRead);
IOUtils.closeRandomAccessFile(rafWrite);
}
}
}
===================IOUtils工具类=====================
public class IOUtils {
public static void closeInputStream(InputStream is){//传入的是具体的子类
if (is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
is = null;
}
}
public static void closeOutputStream(OutputStream os){
if (os != null){
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
os = null;
}
}
public static void closeReader(Reader reader){
if (reader != null){
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
reader = null;
}
}
public static void closeWriter(Writer writer){
if (writer != null){
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
writer = null;
}
}
public static void closeRandomAccessFile(RandomAccessFile raf){
if (raf != null){
try {
raf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
raf = null;
}
}
}