I have one file example.tar.gz and I need to copy it to another location with different name
example _test.tar.gz. I have tried with
private void copyFile(File srcFile, File destFile) throws IOException {
InputStream oInStream = new FileInputStream(srcFile);
OutputStream oOutStream = new FileOutputStream(destFile);
// Transfer bytes from in to out
byte[] oBytes = new byte[1024];
int nLength;
BufferedInputStream oBuffInputStream = new BufferedInputStream(oInStream);
while((nLength = oBuffInputStream.read(oBytes)) > 0) {
oOutStream.write(oBytes, 0, nLength);
}
oInStream.close();
oOutStream.close();
}
where
String from_path = new File("example.tar.gz");
File source = new File(from_path);
File destination = new File("/temp/example_test.tar.gz");
if(!destination.exists())
destination.createNewFile();
and then
copyFile(source, destination);
It doesn't work. The path is correct. It prints that the file exists. Can anybody help me?
Why to reinvent the wheel, just use FileUtils.copyFile(File srcFile, File destFile) , this will handle many scenarios for you
I would suggest Apache commons FileUtils or NIO (direct OS calls)
or Just this
Credits to Josh - standard-concise-way-to-copy-a-file-in-java
File source=new File("example.tar.gz");
File destination=new File("/temp/example_test.tar.gz");
copyFile(source,destination);
Updates:
Changed to transferTo from #bestss
public static void copyFile(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new RandomAccessFile(sourceFile,"rw").getChannel();
destination = new RandomAccessFile(destFile,"rw").getChannel();
long position = 0;
long count = source.size();
source.transferTo(position, count, destination);
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
There is Files class in package java.nio.file. You can use the copy method.
Example: Files.copy(sourcePath, targetPath).
Create a targetPath object (which is an instance of Path) with the new name of your file.
Related
One application I had been using required all classes to be in the same base hierarchy (Meaning jars could not be inside the jar or else it would fail) for whatever reason. Because I was creating my own application for others to use, I had no control over whether or not they had a fat jar or not, so I had to figure out a way to "fatten?" an already made jar.
One could use the JarFile and everytime they encountered a jar file, write the jar into its own file and do it over again; however, that feels like an absolute waste of memory and time to copy stuff over like that just to have access to the JarFile entry list
Ex: test.jar
-com.package
-main.class
-dependency1.jar
-com.depedency1
-test.class
and what was needed:
test.jar
-com.package
-main.class
-com.dependency1
-test.class
Here is the solution I made for this problem, although it doesn't handle naming collisions that well.
The readJar could be helpful for several other tasks if you want to read all the classes in a jar.
public class JarUtils extends Base {
public static File fatJar(File dest, File file) throws IOException {
finer("Generating Fat Jar:" + file);
try (JarInputStream zis = new JarInputStream(new BufferedInputStream(new FileInputStream(file)));
JarOutputStream zos = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)), zis.getManifest())) {
final byte[] buffer = new byte[1024];
readJar(file.getName(), zis, (entry, is) -> {
int len;
zos.putNextEntry(entry);
while ((len = is.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
}, new ArrayList<>());
zos.finish();
}
return dest;
}
private static void readJar(String jarName, JarInputStream zis, JarEntryWalker walker, List<String> checkedEntries) throws IOException {
ZipEntry entry;
if (!jarName.endsWith("/")) jarName += "/";
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().contains(".jar")) {
readJar(entry.getName(), new JarInputStream(zis), walker, checkedEntries);
} else {
String name = (entry.getName().contains("META-INF/") ? jarName : "") + entry.getName();
if (!checkedEntries.contains(name)) {
ZipEntry zipEntry = new ZipEntry(name);
zipEntry.setComment(entry.getComment());
zipEntry.setExtra(entry.getExtra());
zipEntry.setCreationTime(entry.getCreationTime());
zipEntry.setLastAccessTime(entry.getLastAccessTime());
zipEntry.setLastModifiedTime(entry.getLastModifiedTime());
walker.entry(zipEntry, zis);
checkedEntries.add(name);
}
}
}
}
}
interface JarEntryWalker {
void entry(ZipEntry zipEntry, InputStream is) throws IOException;
}
So I have been working with a Derby DB and can write to and work with the data. I'm now trying to pack it into a single archive file(jar). I can get it to pack and unpack with no issues. Well except one.
I can get it to pack into a jar but it has an extra folder depth. So if I pack up the directory that is named "December", and inside that archive I also get a "December" folder with the contents inside it. Is there a way I can remove that extra folder either in packing or unpacking?
I have tried to play with the file's name but if I mess with it I get errors saying it can't find the file after I renamed it. I tried this both before it's packed and while unpacking it. Closes I got was each file name in the main directory but all the files are 0kb. I even try to change the pack directory to "December*", but it didn't like that.
public class JarPack {
public static void pack(String name,String dir) throws FileNotFoundException, IOException{
System.out.println(dir);
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
JarOutputStream target = new JarOutputStream(new FileOutputStream(name), manifest);
add(new File(dir), target);
target.close();
}
private static void add(File source, JarOutputStream target) throws IOException{
BufferedInputStream in = null;
try
{
if (source.isDirectory())
{
String name = source.getPath().replace("\\", "/");
if (!name.isEmpty())
{
if (!name.endsWith("/"))
name += "/";
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File nestedFile: source.listFiles())
add(nestedFile, target);
return;
}
JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
entry.setTime(source.lastModified());
target.putNextEntry(entry);
in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true)
{
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
}
finally{
if (in != null)
in.close();
}
}
#SuppressWarnings("resource")
public static void unPack(String name,String dir) throws java.io.IOException {
java.util.jar.JarFile jarfile = new java.util.jar.JarFile(new java.io.File(name));
java.util.Enumeration<java.util.jar.JarEntry> enu= jarfile.entries();
while(enu.hasMoreElements()){
String destdir = dir;
java.util.jar.JarEntry je = enu.nextElement();
if (!je.getName().equals("META-INF/MANIFEST.MF")){
java.io.File fl = new java.io.File(destdir, je.getName());
if(!fl.exists()){
fl.getParentFile().mkdirs();
fl = new java.io.File(destdir, je.getName());
}
if(je.isDirectory()){
continue;
}
java.io.InputStream is = jarfile.getInputStream(je);
java.io.FileOutputStream fo = new java.io.FileOutputStream(fl);
while(is.available()>0){
fo.write(is.read());
}
fo.close();
is.close();
}
}
}
}
I am not able delete file that is stored in cache. I am using the cache for several purposes. I am reading and writing but not able to delete. Can someone please help me with this?
//write
public static void writeObject(Context context, String key, Object object)
throws IOException {
Log.d("Cache", "WRITE: context");
FileOutputStream fos = context.openFileOutput(key, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
fos.close();
}
//read
public static Object readObject(Context context, String key) throws IOException,
ClassNotFoundException {
FileInputStream fis = context.openFileInput(key);
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
return object;
}
//delete
public static void clearCahe(String key) throws IOException,ClassNotFoundException {
File file = new File(key);
file.delete();
}
context.openFileOutput(key writes the file to internal memory. The path you can find with getFilesDir() and looks like /data/data/<yourpackagename>/files.
So if you want to delete the file 'key' you have to set up the path for File file = new File(path) as String path = getFilesDir().getAbsolutePath() + "/" + key;.
And use file.exists() to check if the file exists!
use this to clear application data.
public void clearApplicationData()
{
File cache = getCacheDir();
File appDir = new File(cache.getParent());
if (appDir.exists()) {
String[] children = appDir.list();
for (String s : children) {
if (!s.equals("lib")) {
deleteDir(new File(appDir, s));Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
}
}
}
}
public static boolean deleteDir(File dir)
{
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
return dir.delete();
}
Files
Like the cache directory, your app also has an app-specific directory for holding files. Files in this directory will exist until the app explicitly deletes them or the app is uninstalled. You typically access this directory with Context.getFilesDir(). This can show up as various things on the app info screen, but in your screenshot this is "USB Storage Data".
NOTE: If you want to explicitly place on external media (typically SD card), you can use Context.getExternalFilesDir(String type).
Simple cache manager:
public class CacheManager {
private static final long MAX_SIZE = 5242880L; // 5MB
private CacheManager() {
}
public static void cacheData(Context context, byte[] data, String name) throws IOException {
File cacheDir = context.getCacheDir();
long size = getDirSize(cacheDir);
long newSize = data.length + size;
if (newSize > MAX_SIZE) {
cleanDir(cacheDir, newSize - MAX_SIZE);
}
File file = new File(cacheDir, name);
FileOutputStream os = new FileOutputStream(file);
try {
os.write(data);
}
finally {
os.flush();
os.close();
}
}
public static byte[] retrieveData(Context context, String name) throws IOException {
File cacheDir = context.getCacheDir();
File file = new File(cacheDir, name);
if (!file.exists()) {
// Data doesn't exist
return null;
}
byte[] data = new byte[(int) file.length()];
FileInputStream is = new FileInputStream(file);
try {
is.read(data);
}
finally {
is.close();
}
return data;
}
private static void cleanDir(File dir, long bytes) {
long bytesDeleted = 0;
File[] files = dir.listFiles();
for (File file : files) {
bytesDeleted += file.length();
file.delete();
if (bytesDeleted >= bytes) {
break;
}
}
}
private static long getDirSize(File dir) {
long size = 0;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
size += file.length();
}
}
return size;
}
}
NOTE: The purpose of the cache is to cut down on network activity,
long processes, and provide a responsive UI in your app.
Reference: When to clear the cache dir in Android?.
I am using JDK 6.
I have 2 folders names are Folder1 and Folder2.
Folder1 have the following files
TherMap.txt
TherMap1.txt
TherMap2.txt
every time Folder2 have only one file with name as TherMap.txt.
What I want,
copy any file from folder1 and pasted in Folder2 with name as TherMap.txt.If already TherMap.txt exists in Folder2, then delete and paste it.
for I wrote the following code.but it's not working
public void FileMoving(String sourceFilePath, String destinationPath, String fileName) throws IOException {
File destinationPathObject = new File(destinationPath);
File sourceFilePathObject = new File(sourceFilePath);
if ((destinationPathObject.isDirectory()) && (sourceFilePathObject.isFile()))
//both source and destination paths are available
{
//creating object for File class
File statusFileNameObject = new File(destinationPath + "/" + fileName);
if (statusFileNameObject.isFile())
//Already file is exists in Destination path
{
//deleted File
statusFileNameObject.delete();
//paste file from source to Destination path with fileName as value of fileName argument
FileUtils.copyFile(sourceFilePathObject, statusFileNameObject);
}
//File is not exists in Destination path.
{
//paste file from source to Destination path with fileName as value of fileName argument
FileUtils.copyFile(sourceFilePathObject, statusFileNameObject);
}
}
}
I call the above function in main()
//ExternalFileExecutionsObject is class object
ExternalFileExecutionsObject.FileMoving(
"C:/Documents and Settings/mahesh/Desktop/InputFiles/TMapInput1.txt",
"C:/Documents and Settings/mahesh/Desktop/Rods",
"TMapInput.txt");
While I am using FileUtils function, it showing error so I click on error, automatically new package was generated with the following code.
package org.apache.commons.io;
import java.io.File;
public class FileUtils {
public static void copyFile(File sourceFilePathObject,
File statusFileNameObject) {
// TODO Auto-generated method stub
}
}
my code not showing any errors,even it's not working.
How can I fix this.
Thanks
Use Apache Commons FileUtils
FileUtils.copyDirectory(source, desc);
Your code isn't working because in order to use the ApacheCommons solution you will have to download the ApacheCommons library found here:
http://commons.apache.org/
and add a reference to it.
Since you are using JRE 6 you can't use all the NIO file utilities, and despite everyone loving Apache Commons as a quick way to answer forum posts, you may not like the idea of having to add that utility on just to get one function. You can also use this code that uses a transferFrom method without using ApacheCommons.
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileInputStream fIn = null;
FileOutputStream fOut = null;
FileChannel source = null;
FileChannel destination = null;
try {
fIn = new FileInputStream(sourceFile);
source = fIn.getChannel();
fOut = new FileOutputStream(destFile);
destination = fOut.getChannel();
long transfered = 0;
long bytes = source.size();
while (transfered < bytes) {
transfered += destination.transferFrom(source, 0, source.size());
destination.position(transfered);
}
} finally {
if (source != null) {
source.close();
} else if (fIn != null) {
fIn.close();
}
if (destination != null) {
destination.close();
} else if (fOut != null) {
fOut.close();
}
}
}
When you upgrade to 7, you will be able to do the following
public static void copyFile( File from, File to ) throws IOException {
Files.copy( from.toPath(), to.toPath() );
}
reference:
https://gist.github.com/mrenouf/889747
Standard concise way to copy a file in Java?
I want to copy a file from one location to another location in Java. What is the best way to do this?
Here is what I have so far:
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
public class TestArrayList {
public static void main(String[] args) {
File f = new File(
"D:\\CBSE_Demo\\Demo_original\\fscommand\\contentplayer\\config");
List<String>temp=new ArrayList<String>();
temp.add(0, "N33");
temp.add(1, "N1417");
temp.add(2, "N331");
File[] matchingFiles = null;
for(final String temp1: temp){
matchingFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith(temp1);
}
});
System.out.println("size>>--"+matchingFiles.length);
}
}
}
This does not copy the file, what is the best way to do this?
You can use this (or any variant):
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
Also, I'd recommend using File.separator or / instead of \\ to make it compliant across multiple OS, question/answer on this available here.
Since you're not sure how to temporarily store files, take a look at ArrayList:
List<File> files = new ArrayList();
files.add(foundFile);
To move a List of files into a single directory:
List<File> files = ...;
String path = "C:/destination/";
for(File file : files) {
Files.copy(file.toPath(),
(new File(path + file.getName())).toPath(),
StandardCopyOption.REPLACE_EXISTING);
}
Update:
see also
https://stackoverflow.com/a/67179064/1847899
Using Stream
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
Using Channel
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
Using Apache Commons IO lib:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
Using Java SE 7 Files class:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
Or try Googles Guava :
https://github.com/google/guava
docs:
https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/io/Files.html
Use the New Java File classes in Java >=7.
Create the below method and import the necessary libs.
public static void copyFile( File from, File to ) throws IOException {
Files.copy( from.toPath(), to.toPath() );
}
Use the created method as below within main:
File dirFrom = new File(fileFrom);
File dirTo = new File(fileTo);
try {
copyFile(dirFrom, dirTo);
} catch (IOException ex) {
Logger.getLogger(TestJava8.class.getName()).log(Level.SEVERE, null, ex);
}
NB:- fileFrom is the file that you want to copy to a new file fileTo in a different folder.
Credits - #Scott: Standard concise way to copy a file in Java?
public static void copyFile(File oldLocation, File newLocation) throws IOException {
if ( oldLocation.exists( )) {
BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );
BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
try {
byte[] buff = new byte[8192];
int numChars;
while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {
writer.write( buff, 0, numChars );
}
} catch( IOException ex ) {
throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());
} finally {
try {
if ( reader != null ){
writer.close();
reader.close();
}
} catch( IOException ex ){
Log.e(TAG, "Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
} else {
throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
Copy a file from one location to another location means,need to copy the whole content to another location.Files.copy(Path source, Path target, CopyOption... options) throws IOException this method expects source location which is original file location and target location which is a new folder location with destination same type file(as original).
Either Target location needs to exist in our system otherwise we need to create a folder location and then in that folder location we need to create a file with the same name as original filename.Then using copy function we can easily copy a file from one location to other.
public static void main(String[] args) throws IOException {
String destFolderPath = "D:/TestFile/abc";
String fileName = "pqr.xlsx";
String sourceFilePath= "D:/TestFile/xyz.xlsx";
File f = new File(destFolderPath);
if(f.mkdir()){
System.out.println("Directory created!!!!");
}
else {
System.out.println("Directory Exists!!!!");
}
f= new File(destFolderPath,fileName);
if(f.createNewFile()) {
System.out.println("File Created!!!!");
} else {
System.out.println("File exists!!!!");
}
Files.copy(Paths.get(sourceFilePath), Paths.get(destFolderPath, fileName),REPLACE_EXISTING);
System.out.println("Copy done!!!!!!!!!!!!!!");
}
You can do it with the Java 8 Streaming API, PrintWriter and the Files API
try (PrintWriter pw = new PrintWriter(new File("destination-path"), StandardCharsets.UTF_8)) {
Files.readAllLines(Path.of("src/test/resources/source-file.something"), StandardCharsets.UTF_8)
.forEach(pw::println);
}
If you want to modify the content on-the-fly while copying, check out this link for the extended example https://overflowed.dev/blog/copy-file-and-modify-with-java-streams/
I modified one of the answers to make it a bit more efficient.
public void copy(){
InputStream in = null;
try {
in = new FileInputStream(Files);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
OutputStream out = new FileOutputStream();
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
while (true) {
int len = 0;
try {
if (!((len = in.read(buf)) > 0)) break;
} catch (IOException e) {
e.printStackTrace();
}
try {
out.write(buf, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void moveFile() {
copy();
File dir = getFilesDir();
File file = new File(dir, "my_filename");
boolean deleted = file.delete();
}
Files.exists()
Files.createDirectory()
Files.copy()
Overwriting Existing Files:
Files.move()
Files.delete()
Files.walkFileTree()
enter link description here
You can use
FileUtils.copy(sourceFile, destinationFile);
https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html