-
java文件拷贝的代码改进 0
请看下面的代码,是一个典型的copy文件的例子,我需要一些改进.
现在的情况是,从源文件中读取一部分数据,然后等待输入到目标文件,然后再开始读,一直重复.
这样效率太低,因為只有一個線程在工作,因为每次读完,都要等待写入以后才开始第二次读入.
如何改进呢?我想一個線程读一個線程写,当缓存数组中有数据就写,没有的话就等待读入缓存数组之后再写,這樣可以大大的節約很多時間.代码如何改?
public void copy(File f1,File f2) throws IOException { //创建文件输入流对象 FileInputStream rf = new FileInputStream(f1); FileOutputStream wf = new FileOutputStream(f2); //创建文件输出流对象 int count,n=512; byte buffer[] = new byte[n]; count = rf.read(buffer,0,n); //读取输入流 while (count != -1) { wf.write(buffer,0,count); //写入输出流 count = rf.read(buffer,0,n); } System.out.println("CopyFile "+f2.getName()+" !"); rf.close(); //关闭输入流 wf.close(); //关闭输出流 }
2012年8月31日 09:12
6个答案 按时间排序 按投票排序
-
个人认为还是单线程的最快,毕竟瓶颈在io这里。
1. io同一时刻只能读取一块(多磁盘或多磁头或阵列另算)
2. 提升io:磁头的移动尽可能的少(如果多线程争抢io,必然导致磁头频繁动作切换)
目前操作系统都会很好的优化你的磁盘读取的,那么关键是怎样利用OS的磁盘缓存。推荐使用java的直接内存映像操作文件系统。
private static void copy(File src, Path dist) throws IOException { if (src.isDirectory()) { if (!Files.exists(dist)) Files.createDirectories(dist); for (File child : src.listFiles()) { copy(child, dist.resolve(child.getName())); } } else { try (FileInputStream fin = new FileInputStream(src); FileOutputStream fout = new FileOutputStream(dist.toFile())) { fin.getChannel().transferTo(0, src.length(), fout.getChannel()); } } } private static void copy2(File src, Path dist) throws IOException { if (src.isDirectory()) { if (!Files.exists(dist)) Files.createDirectories(dist); for (File child : src.listFiles()) { copy(child, dist.resolve(child.getName())); } } else { try (FileInputStream fin = new FileInputStream(src); FileOutputStream fout = new FileOutputStream(dist.toFile())) { int len; byte[] buf = new byte[2048]; while ((len = fin.read(buf)) != -1) { fout.write(buf, 0, len); } } } }
2012年8月31日 17:06
-
package bluechip.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class FileUtils { private static final int DEFAULT_BUFFER_SIZE = 8192; static class Producer implements Runnable { private final BlockingQueue<byte[]> queue; private File src; private boolean eof; private InputStream in; Producer(BlockingQueue<byte[]> q, File src) { queue = q; this.src = src; } public void run() { try { while (!eof) { queue.put(produce()); } } catch (InterruptedException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } System.out.println("Reader done!"); } private InputStream getInputStream() throws FileNotFoundException { if (in == null) { in = new FileInputStream(src); } return in; } byte[] produce() throws FileNotFoundException, IOException { byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; int len = getInputStream().read(buf); if (len == -1) { eof = true; return null; } else if (len == DEFAULT_BUFFER_SIZE) { return buf; } else { eof = true; byte[] b = new byte[len]; System.arraycopy(buf, 0, b, 0, len); return b; } } } static class Consumer implements Runnable { private final BlockingQueue<byte[]> queue; private File dest; private OutputStream out; private boolean active; Consumer(BlockingQueue<byte[]> q, File dest) { queue = q; this.dest = dest; } private OutputStream getOutputStream() throws FileNotFoundException { if (out == null) { out = new FileOutputStream(dest); } return out; } public void run() { active = true; try { while (active) { consume(queue.take()); } } catch (InterruptedException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } System.out.println("Writer done!"); } void consume(byte[] b) throws FileNotFoundException, IOException { if (b == null) { active = false; return; } if (b.length < DEFAULT_BUFFER_SIZE) { active = false; } getOutputStream().write(b); } } public static void copyFile(File src, File dest) { BlockingQueue<byte[]> q = new ArrayBlockingQueue<byte[]>(10); Producer p = new Producer(q, src); Consumer c = new Consumer(q, dest); Thread t1 = new Thread(p); t1.start(); Thread t2 = new Thread(c); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { } } /** * @param args */ public static void main(String[] args) { copyFile(new File("d:/Testing for Non.docx"), new File("d:/1.docx")); } }
2012年8月31日 16:02
-
生产者-消费者模式
package bluechip.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class FileUtils {
private static final int DEFAULT_BUFFER_SIZE = 8192;
static class Producer implements Runnable {
private final BlockingQueue<byte[]> queue;
private File src;
private boolean eof;
private InputStream in;
Producer(BlockingQueue<byte[]> q, File src) {
queue = q;
this.src = src;
}
public void run() {
try {
while (!eof) {
queue.put(produce());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Reader done!");
}
private InputStream getInputStream() throws FileNotFoundException {
if (in == null) {
in = new FileInputStream(src);
}
return in;
}
byte[] produce() throws FileNotFoundException, IOException {
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int len = getInputStream().read(buf);
if (len == -1) {
eof = true;
return null;
} else if (len == DEFAULT_BUFFER_SIZE) {
return buf;
} else {
eof = true;
byte[] b = new byte[len];
System.arraycopy(buf, 0, b, 0, len);
return b;
}
}
}
static class Consumer implements Runnable {
private final BlockingQueue<byte[]> queue;
private File dest;
private OutputStream out;
private boolean active;
Consumer(BlockingQueue<byte[]> q, File dest) {
queue = q;
this.dest = dest;
}
private OutputStream getOutputStream() throws FileNotFoundException {
if (out == null) {
out = new FileOutputStream(dest);
}
return out;
}
public void run() {
active = true;
try {
while (active) {
consume(queue.take());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Writer done!");
}
void consume(byte[] b) throws FileNotFoundException, IOException {
if (b == null) {
active = false;
return;
}
if (b.length < DEFAULT_BUFFER_SIZE) {
active = false;
}
getOutputStream().write(b);
}
}
public static void copyFile(File src, File dest) {
BlockingQueue<byte[]> q = new ArrayBlockingQueue<byte[]>(10);
Producer p = new Producer(q, src);
Consumer c = new Consumer(q, dest);
Thread t1 = new Thread(p);
t1.start();
Thread t2 = new Thread(c);
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
}
}
/**
* @param args
*/
public static void main(String[] args) {
copyFile(new File("d:/Testing for Non.docx"), new File("d:/1.docx"));
}
}2012年8月31日 16:02
-
在 common-io 2.1.jar 的 源码中, 采用的 方法 是 FileChannel
/** * Internal copy file method. * * @param srcFile the validated source file, must not be <code>null</code> * @param destFile the validated destination file, must not be 在 common-io 2.1的 源码中提供了一个 copy的 方法 ,采用的 是 <code>null</code> * @param preserveFileDate whether to preserve the file date * @throws IOException if an error occurs */ private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { if (destFile.exists() && destFile.isDirectory()) { throw new IOException("Destination '" + destFile + "' exists but is a directory"); } FileInputStream fis = null; FileOutputStream fos = null; FileChannel input = null; FileChannel output = null; try { fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); input = fis.getChannel(); output = fos.getChannel(); long size = input.size(); long pos = 0; long count = 0; while (pos < size) { count = (size - pos) > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : (size - pos); pos += output.transferFrom(input, pos, count); } } finally { IOUtils.closeQuietly(output); IOUtils.closeQuietly(fos); IOUtils.closeQuietly(input); IOUtils.closeQuietly(fis); } if (srcFile.length() != destFile.length()) { throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); } if (preserveFileDate) { destFile.setLastModified(srcFile.lastModified()); } }
2012年8月31日 11:20
-
觉得没必要多线程。效率低不低是要实验数据来说话的。
小文件加个BufferedReader缓存一下,大文件用NIO就可以了。
或者如楼上所说用commons io。2012年8月31日 09:19
-
建议直接使用 apache的 commons io 工具包 里边有关于io操作的详细工具类;简化开发
如FileUtil2012年8月31日 09:14
相关推荐
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
而且,作为开源软件,FastCopy的源代码公开,开发者社区会持续改进和维护,确保软件的稳定性和兼容性。 总的来说,无论是日常的工作备份,还是开发者处理大型项目,FastCopy 2.01都能提供强大的文件拷贝支持。它以...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程...
NIO2引入了许多改进,包括异步文件操作、文件系统感知以及更强大的文件拷贝功能。本示例将详细讲解如何使用Java NIO2来高效地拷贝文件。 首先,我们看到代码中定义了一个名为`MyFiles2`的类,这个类用于实现文件或...
标题 "Postman拷贝下来的代码调通的依赖包.zip" 提示我们这是一份与Postman相关的代码,可能包含了在Postman中复制的API请求代码,用于在Java环境中调用和测试HTTP接口。描述中的信息进一步确认了这个点,表明这个...
在这个实例089中,我们可以期待看到如何在具体编程环境中实现文件拷贝功能,例如可能的优化策略、错误处理机制以及与其他系统功能(如多线程或网络传输)的整合。不过,由于没有提供具体的源码内容,我们无法深入...
很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256位...
JDK1.7,即Java SE 7,是Oracle公司发布的一个重要版本,它在Java 6的基础上引入了许多新特性和改进,对开发者来说具有重要意义。 标题中的“JDK1.7 无需安装,拷贝直接用”指的是这个版本的JDK可以直接解压使用,...
根据提供的文件信息,我们可以深入分析并提取出与Java复数程序相关的知识点: ### 1. 复数类的定义 #### (1)基础版本 `Complex` 类定义 ```java public class Complex { double real, imag; // 实部和虚部 ...
- **日志记录**:为了更好地跟踪程序运行情况,可以在程序中加入日志记录功能,记录文件拷贝的状态和进度。 - **界面交互**:如果是在桌面应用中使用,可以添加图形界面,提供更友好的用户交互体验。 综上所述,...
很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256位...
之前的版本中,字符串连接通常涉及多次内存分配和拷贝,而Java 7改进了字符串连接性能,当字符串数量较少时,使用StringBuilder优化内部实现。 5. **增强的for循环(遍历数组和集合)** Java 7允许在for-each循环...
众所周知,java编译后的class文件是一种中间字节字文件,很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式,但这样会带来很多麻烦,而且也不能真正保护class文件,本工具是对class文件...
文件中的“公共交换乘乘算法.java”可能是一种改进的搜索或交换算法。 4. **文件操作与配置文件读取**:“加载并读取配置文件.java”和“加载并读取配置文件例子【DBCon】.java”涉及到的是I/O流和资源管理,Java的...
首先,Lua 5.3.3是Lua语言的一个版本,它提供了一些新特性,比如改进的数字处理、元表的隐式拷贝以及新的语法结构。在Android中使用Lua,我们需要将它的源码编译为适用于Android的二进制库。这通常涉及到使用Android...
11. **改进的数组复制**:`System.arraycopy()`方法现在能处理数组的拷贝,包括源和目标数组的类型不完全匹配的情况。 12. **并行流(Parallel Streams)**:Java 7引入了并行流,使得在集合上进行并行操作变得更加...