• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Copying files

 
Tapan Parikh
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

How do I use Java to copy files from one dir to another? More generally, how do I interact w/ the file system and do various other system calls in java?
tankx in advance, tap
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should check out the class java.io.File, which has a number of methods that may be of use to you. Unfortunately, copying files is not supported directly - you have to open a stream to read the file you want to copy, and open another stream to write the copied file. Then loop to read from one and copy to the other. Here's some code I use for this:
<code><pre>
public static void copyFile(File source, File dest)
throws IOException {
BufferedInputStream in= null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(source));
out = new BufferedOutputStream(new FileOutputStream(dest));
copyStream(in, out);
}
finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
}

public static void copyStream(InputStream in, OutputStream out)
throws IOException {
byte[] buffer = new byte[1024];
int numberRead;
while ((numberRead = in.read(buffer)) >= 0) {
out.write(buffer, 0, numberRead);
}
}
</pre></code>
The latter method is useful for more than just copying files, which is why I make it a separate method. I never got around to experimenting with the buffer size to find what size works best - it probably depends on the average file size you're dealing with. Enjoy...
 
Tapan Parikh
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

But isnt this much slower than the OS mechanism for copying files?
Im trying to copy potentially large directories with large binary files in them. It seems doing this through streams is gonna be really, really slow...
--tap
 
Vlad Patryshev
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are right, this is extremely inefficient. The problem is, there seems to be no platform-independent way of handling file copy.
I had the same issue with my Perl scripts; you can handle it, though, if you know in advance the range of platforms, and prepare solutions for all of them (well, still a problem in Windows, where copy command has many different flavors, depending).
 
Frank Ying
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the above solution is hard copy, byte-to-byte, you can use Runtime.exec("cp XX XX"), OS may find a way to just change dir.
Frank
 
Vlad Patryshev
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Frank Ying:
the above solution is hard copy, byte-to-byte, you can use Runtime.exec("cp XX XX"), OS may find a way to just change dir.
Frank

And then you will want to
a) replace "cp" with "copy" for certain Microsoft platforms;
b) add certain flags (-V, e.g.), depending on the platform;
c) have your file paths, XX and XX, with correct slashes;
d) in case you copy a directory, add more flags, depending on the platform;
e) plug and pray if you run this on enigmatic platforms like Mac, Next, and whatever there is around. Palm Pilot, e.g.
 
Tapan Parikh
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I tried doing this using Runtime on Win98, but Im getting the following exception...
Here is my code:
-----------------
private static void copyDataFiles(String src, String dest)
throws IOException
{
System.out.println("Copying files from " + src + " to " + dest + "...");
(new File(dest)).mkdirs();
Runtime rt = Runtime.getRuntime();
String cmd = "copy " + src + "\\*.* " + dest;
System.out.println(cmd);
rt.exec(cmd);
}
--------------
And here is the exception...
---------------
Copying files from data\lang\eng to upload\data\lang\eng...
copy data\lang\eng\*.* upload\data\lang\eng
java.io.IOException: CreateProcess: copy data\lang\eng\*.* upload\data\lang\eng error=0
java.io.IOException: CreateProcess: copy data\lang\eng\*.* upload\data\lang\eng error=0
at java.lang.Win32Process.create(Native Method)
at java.lang.Win32Process.<init>(Win32Process.java:64)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:272)
at java.lang.Runtime.exec(Runtime.java:195)
at java.lang.Runtime.exec(Runtime.java:152)
at XMLGenerator.copyDataFiles(XMLGenerator.java:130)
at XMLGenerator.generateFile(XMLGenerator.java, Compiled Code)
at XMLGenerator.gen_files(XMLGenerator.java, Compiled Code)
at XMLGenerator.main(XMLGenerator.java:17)
Error!
--------------
Ive tried using the /V option too, and Ive made sure all directories exist. If I run the same cmd from the DOS prompt it works.
Any ideas? TIA... --tap
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Regarding speed of this method - yeah, you'd think that this would be slower than letting the OS do the copying for you - but the other day, my lowly Java program was consistently outperforming both Windows Explorer and a command-line xcopy, in transferring large files across a network. I doubt that's normal - there was something wrong with the network at the time, I suspect - but it was definitely true for me, this one time at least. Go figure.
the above solution is hard copy, byte-to-byte, you can use Runtime.exec("cp XX XX"), OS may find a way to just change dir.

??? Perhaps you are thinking of moving/renaming a file, as opposed to copying it? To make a copy, you (or the OS) must copy each byte - when you are done, there are two distinct files, taking up twice as much space as before. Moving or renaming is considerably easier - most of the file can remain untouched, and only the directory entries need be altered in order for a file to appear to be moved to a different directory. Of course, Java accomplished this easily with the rename() method, also in the File class.
Tapan - for your IOException, I'm guessing that the Runtime invocation of "copy" bypasses the command-line wildcard substitution. That is, "*.*" is unrecognized. Try naming specific files in your command, and see if it works. If so, then you can use the File list() command to get the names of all files in a directory, and run a separate copy process for each one. Which does seem inelegant - there may be a better way, but I'm not very skilled in Windows command-line options. Good luck...
 
Ryan Langley
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,
I'm not sure why you want to copy all files in one directory to another, but if you're doing it so that you can overwite/delete the original files in the initial directory then you may want to check out the renameTo() method of the File class. It can be used to effectively move the files from one directory to another. Here's a quick program I wrote to illustrate this:

I haven't tried this on extremely large files, so I don't know how fast it would work on those. Just a simple solution if that is what you're lookign for.. Good luck!

------------------
Cheers,
RL
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oops - my previous post referred to the "rename()" method in File, which of course is really "renameTo()", as Ryan points out. As we all agree, this will be faster than copying (i.e. creating two files in different directories) if that's what you need.
 
Dilshad Marikar
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought i'd add something to this old thread.
I was trying to use the info on thread to copy files using Runtime.exec, but came across the same problem as Tapan did. I found this excellent article on the problem at Java World. Basically, the issue is that we are need to grab any error messages and output from the external program we're calling. Here is a code sample based on the article which I used to copy files:



[ November 23, 2004: Message edited by: Ernest Friedman-Hill ]
 
Dilshad Marikar
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmm, i'm not sure why i've lost indentation when i pasted code..
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Mohammed Dilsard:
hmm, i'm not sure why i've lost indentation when i pasted code..


Because you have to use UBB "CODE" tags when you post code. I edited your message to include them.
 
Joe Ess
Bartender
Posts: 9340
10
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The NIO API (JDK 1.4+) introduced a slick way to copy files using channels:



Technical Articles and Tips: File Channels and Stack Trace Elements

Consise, efficient AND cross-platform, like Java should be.
 
Dilshad Marikar
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for sorting out my code Ernest. Your book is pretty good by the way!
 
Marian Olteanu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Tapan Parikh:
[QB]OK, I tried doing this using Runtime on Win98, but Im getting the following exception...

Here is my code:
-----------------
private static void copyDataFiles(String src, String dest)
throws IOException
{
System.out.println("Copying files from " + src + " to " + dest + "...");
(new File(dest)).mkdirs();
Runtime rt = Runtime.getRuntime();
String cmd = "copy " + src + "\\*.* " + dest;
System.out.println(cmd);
rt.exec(cmd);
}
--------------

And here is the exception...
---------------
Copying files from data\lang\eng to upload\data\lang\eng...
copy data\lang\eng\*.* upload\data\lang\eng
java.io.IOException: CreateProcess: copy data\lang\eng\*.* upload\data\lang\eng error=0
java.io.IOException: CreateProcess: copy data\lang\eng\*.* upload\data\lang\eng error=0


The explanation is that "copy" is an internal command of the command.com program.
If you want to execute "copy" then you need to do execute like this:
String cmd = "command.com /ccopy " + src + "\\*.* " + dest;
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic