Hello i`ve made a program where i unmarshall XML file, get those informations and use them for connecting to server and move files to another folder.
The program goes like this:
1.get the informations from xml
2.connect and upload them to server
3.move the files that have been uploaded to another folder locally.
The problem is when i put Object and method of Upload. The upload is okay, the files are uploaded, new folders are created for files to move there, but the files dont move, they are in the same directory.
If i put Move object and method above Upload its opposite. The files are moved to another folder(locally) but they are not uploaded...
What can be the problem and how to fix this?
Thank you!
Here is my method for marsh and there i use both methods(upload and move):
public void unmarshallList() {
try {
JAXBContext jc = JAXBContext.newInstance(ListNodes.class);
Unmarshaller ums = jc.createUnmarshaller();
ListNodes ln = (ListNodes) ums.unmarshal(new File("C:\\Users\\Desktop\\marshList.xml"));
System.out.println("INFORMATIONS");
System.out.println("-------------------------------");
for (Node p : ln.getListNode()) {
System.out.println("Hostname: " + p.getHostname());
System.out.println("Username: " + p.getUsername());
System.out.println("Password: " + p.getPassword());
System.out.println("Port: " + p.getPort());
System.out.println("Pc Directory: " + p.getPcDirectory());
System.out.println("Node Directory: " + p.getNodeDirectory());
System.out.println("Time interval: " + p.getTimeInterval());
System.out.println("Move Directory" + p.getMoveDir());
System.out.println("-------------------------------");
Upload up = new Upload();
up.connection(p.getHostname(), p.getPort(), p.getUsername(), p.getPassword(), p.getNodeDirectory(), p.getPcDirectory(), p.getTimeInterval(), p.getMoveDir());
Move mv = new Move();
mv.moveFiles(p.getPcDirectory(), p.getMoveDir());
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
}
And here is my move method:
public static void moveFiles (String oldLocation, String newLocation) {
File source = new File(oldLocation);
File dest = new File(newLocation);
new File(newLocation).mkdir();
File[] files = source.listFiles();
for (File file : source.listFiles()) {
System.out.println(source + "\\" + file.getName());
String x = (source + "\\" + file.getName());
String y = (dest + "\\" + file.getName());
File f1 = new File(x);
f1.renameTo(new File(y));
System.out.println("This file is moved "+x );
}
System.out.println("The files are moved" );
}
And here is the upload method:
private static void recursiveFolderUpload(String sourcePath, String
destinationPath) throws SftpException, FileNotFoundException {
File sourceFile = new File(sourcePath);
if (sourceFile.isFile()) {
// copy if it is a file
channelSftp.cd(destinationPath);
if (!sourceFile.getName().endsWith(".xml"));
channelSftp.put(new FileInputStream(sourceFile), sourceFile.getName(), ChannelSftp.OVERWRITE);
} else {
System.out.println("inside " + sourceFile.getName());
File[] files = sourceFile.listFiles();
if (files != null && !sourceFile.getName().endsWith(".xml")) {
channelSftp.cd(destinationPath);
SftpATTRS attrs = null;
// check if the directory is already existing
try {
attrs = channelSftp.stat(destinationPath + "/" + sourceFile.getName());
} catch (Exception e) {
System.out.println(destinationPath + "/" + sourceFile.getName() + " not found");
}
// else create a directory
if (attrs != null) {
System.out.println("Directory exists IsDir=" + attrs.isDir());
} else {
System.out.println("Creating dir " + sourceFile.getName());
channelSftp.mkdir(sourceFile.getName());
}
for (File f: files) {
recursiveFolderUpload(f.getAbsolutePath(), destinationPath + "/" + sourceFile.getName());
}
}
}
My guess would be the InputStream of the source file is not closed.
I'd try
InputStream in = new FileInputStream(sourceFile)
try {
channelSftp.put(in, sourceFile.getName(), ChannelSftp.OVERWRITE);
} finally {
in.close();
}
or another way
try (InputStream in = new FileInputStream(sourceFile)) {
channelSftp.put(in, sourceFile.getName(), ChannelSftp.OVERWRITE);
}
which closes the InputStream uppon exiting the try statement.
However - without debugging / any exception message it is almost impossible to be sure
Related
i am using library apache common io to copy file in my java program. when i tried to copy a lot of files (about 250.000) it just copied 4.454 and then stopped copying.
i saw in the task manager it's still running.
public void copyFiles(File source, File dest) {
Collection<File> all = new ArrayList<File>();
try {
addTree(source, all);
for (File elem : all) {
int p = 1;
File newFile = new File(dest.toString() + "\\" + elem.getName().replace(".", " ("+p+")."));
if (findFile(elem.getName(), dest)) {
for (int x = 1; newFile.exists() == true; x++) {
newFile = new File(dest.toString() + "\\" + elem.getName().replace(".", " ("+x+")."));
}
FileUtils.copyFile(elem.getAbsoluteFile(), newFile);
// jika file TIDAK di hidden maka copy file ke direktori
} else if (!(elem.isHidden())) {
FileUtils.copyFileToDirectory(elem, dest);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I have my GWT project and I want to upload files to server. I want the following algorithm to work
1) create a folder with the name from "userNumber"
2) write uploaded files to this folder
3) add folder to zip
4) delete folder (if exists)
As I write on the server side I think it is just java problem. Here is my code. I can perform only the first and the second steps, i.e. I can create a folder and write files to this folder.
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException {
String response = "";
userNumber = request.getParameter("userNumber");
File f = new File(ConfAppServer.getRealContextPath() + "/edoc/"
+ userNumber);
if (f.mkdir()) {
System.out.println("Directory Created");
} else {
System.out.println("Directory is not created");
}
for (FileItem item : sessionFiles) {
if (false == item.isFormField()) {
try {
String extension = item.getName().substring(
item.getName().length() - 3);
File file = null;
file = new File(ConfAppServer.getRealContextPath()
+ "/edoc/"
+ userNumber
+ System.getProperty("file.separator")
+ item.getName().substring(0,
item.getName().length() - 4) + "."
+ extension);
item.write(file);
receivedFiles.put(item.getFieldName(), file);
receivedContentTypes.put(item.getFieldName(),
item.getContentType());
response += "<file-" + cont + "-field>"
+ item.getFieldName() + "</file-" + cont
+ "-field>\n";
response += "<file-" + cont + "-name>" + item.getName()
+ "</file-" + cont + "-name>\n";
response += "<file-" + cont + "-size>" + item.getSize()
+ "</file-" + cont + "-size>\n";
response += "<file-" + cont + "-type>"
+ item.getContentType() + "</file-" + cont
+ "type>\n";
} catch (Exception e) {
throw new UploadActionException(e);
}
}
}
ZipUtils appZip = new ZipUtils(userNumber + ".zip",
ConfAppServer.getRealContextPath() + "/edoc/" + userNumber);
appZip.generateFileList(new File(ConfAppServer.getRealContextPath()
+ "/edoc/" + userNumber));
appZip.zipIt(userNumber + ".zip");
f.delete();
removeSessionFileItems(request);
return "<response>\n" + response + "</response>\n";
}
Here you can find my ZipUtils class.
When I try to delete my folder, nothing happens. The delete() method doesn't work. Help me please!!
My question is how to add folder to zip and then delete this folder.
Use java.nio.file. You won't have the hassle of manipulating the ZIP API yourself:
final Path pathToZip = Paths.get("path", "to", "your", "zip");
final URI uri = URI.create("jar:" + pathToZip.toUri());
final Map<String, ?> env = Collections.singletonMap("create", "true");
try (
final FileSystem fs = FileSystems.getFileSystem(uri, env);
) {
// write files into the zip here.
// See javadoc for java.nio.file.Files and FileSystem.getPath()
}
More details on how to use the API here.
I have a linux java program that is reading and writing to a CIFS mounted Windows file share. See code snippet at bottom.
After execution, there are files named "cifs*" left in the directory. If the target directory is on the local file system, the code works like a champ. However, if the target directory is a CIFS mounted Windows file share, I get the left-over files. I'm not sure what configuration changes I need to make to fix. Any help is greatly appreciated.
FileRenameMutex myFileRenameMutex = new FileRenameMutex("/WindowsMount/MoveLock");
class FileRenameMutex
{
// global variables
String lockFileBasename;
String unusedExtension = "_Unused";
String unusedFilename;
String inUseFilename;
String localMachineAddress;
String formattedTime;
// log4j logger for this class
public static Logger logMutex = Logger.getLogger(FileRenameMutex.class.getName());
public FileRenameMutex(String _lockFileBase) {
this.lockFileBasename = _lockFileBase;
logMutex.debug("FileRenameMutex: Constructor, with file " + lockFileBasename + " user = " + System.getProperty("user.name"));
try {
localMachineAddress = InetAddress.getLocalHost().getHostAddress();
//localMachineAddress = InetAddress.getLocalHost().getHostName();
} catch ( Exception e ) {
localMachineAddress = "UNKNOWN_HOST";
logMutex.error(" Could not determine host address. " + e.getMessage());
}
// set the file names
unusedFilename = lockFileBasename + unusedExtension;
inUseFilename = lockFileBasename + "_" + localMachineAddress;
logMutex.debug(" Local machine = " + localMachineAddress);
logMutex.debug(" Unused file name = " + this.unusedFilename);
logMutex.debug(" In Use file name = " + this.inUseFilename);
}
public boolean tryAcquire() throws InterruptedException {
boolean returnVal = false;
File unusedFile = new File(unusedFilename);
File inUseFile = new File(inUseFilename);
formattedTime = new Date().toString();
String inUseText = "This file created by the Alfresco cron job to MoveFileAndCreateDir "
+ "(move files from Unfiled to Filed folders).\n"
+ "Running on " + localMachineAddress + "\n Started at " + formattedTime + "\n";
try {
FileWriter fstream = new FileWriter(inUseFile);
BufferedWriter out = new BufferedWriter(fstream);
// attempt to rename file
logMutex.debug(" Attempting to rename mutex file " + unusedFilename + " to " + inUseFilename);
if ( unusedFile.renameTo(inUseFile) ) {
logMutex.debug(" Rename to inUse successful");
out.write(inUseText);
out.flush();
out.close();
returnVal = true; // lock was acquired
} else {
// System.out.println("Rename to inUse failed");
logMutex.error(" Rename of " + unusedFilename + " to " + inUseFilename + " failed in tryAcquire().");
}
} catch ( Exception e ) {
throw new InterruptedException("Error acquiring lock in tryAcquire(): " + e.getMessage());
}
return returnVal;
}
public void release() {
File unusedFile = new File(unusedFilename);
File inUseFile = new File(inUseFilename);
String unusedText = "This file was last by the Alfresco cron job to MoveFileAndCreateDir "
+ "Ran on " + localMachineAddress + "\n Started at " + formattedTime + "\n";
try {
FileWriter fstream = new FileWriter(inUseFile);
BufferedWriter out = new BufferedWriter(fstream);
out.write(unusedText);
out.flush();
out.close();
// attempt to rename file
logMutex.debug(" Attempting to rename active mutex file " + inUseFilename + " back to " + unusedFilename);
if ( inUseFile.renameTo(unusedFile) ) {
logMutex.debug(" Rename back to unused successful");
} else {
logMutex.error(" Rename of " + inUseFilename + " to " + unusedFilename + " failed in release().");
}
} catch ( Exception e ) {
logMutex.error("Error resetting lock file in release(): " + e.getMessage());
}
} // release()
} // end of class FileRenameMutex
just a simple question, with a hard (for me) to find answer :D. Here is my code (im going to try to translate the spanish part):
File carpetanueva = new File("C:"+File.separator+"sistema" + File.separator +
fechasal+File.separator+doc);
carpetanueva.mkdirs();
carpetanueva.setWritable(true);
rutadestino = ("c:"+File.separator+"sistema" +
File.separator + fechasal+File.separator +
doc+File.separator+"imagen.jpg");
//realizo la copia de la imagen desde el jfilechooser a su destino:
Path desde = Paths.get(rutaorigen);
Path hacia = Paths.get(rutadestino);
try {
Files.copy(desde, hacia);
JOptionPane.showMessageDialog(null,
"Se adjunto la planilla de ambulancia correctamente");
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "error: "+e.getLocalizedMessage());
}
I get "rutaorigen" (frompath) from a JFileChooser. And I create "rutadestino" (topath) by using some variables so this way i can give an order. The problem is.. .if directories and the file "imagen.jpg" already exists, it gives an error.. (exception).. How can i make to check if image already exists, and if it does, rename the new image to , for example, imagen2? I cant figure out code, because im a newbie, I did a research and couldnt find something like this! Thanks in advance :)
OK, here is a quick solution if src is a Path to the file you want to copy, dst a Path to the file you want to write, and newName a Path to the file you want to rename to:
if (Files.exists(dst))
Files.move(dst, newName);
Files.copy(src, dst);
Note that you can use the methods in Path to facilitate your path building: .resolve(), .resolveSibling(), .relativize().
Edit: here is a function which will return a suitable name given a directory (dir), a base filename baseName and an "extension" (without the dot) extension:
private static Path findFileName(final Path dir, final String baseName,
final String extension)
{
Path ret = Paths.get(dir, String.format("%s.%s", baseName, extension));
if (!Files.exists(ret))
return ret;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
ret = Paths.get(dir, String.format("%s%d.%s", baseName, i, extension));
if (!Files.exists(ret))
return ret;
}
throw new IllegalStateException("What the...");
}
I think this link will help How do I check if a file exists?
So for your case, probably do something like:
File toFile = new File(rutadestino);
if (toFile.exists()) {
// rename file
toFile.renameTo(new File("newFilePath/newName.jpg"));
} else {
// do something if file does NOT exist
}
Hope that helps! For more info, also check the Java Docs for File
sory late. but my code can help to litle bit.
public void copyFile(File source, File dest) throws IOException,
FileAlreadyExistsException {
File[] children = source.listFiles();
if (children != null) {
for (File child : children) {
if (child.isFile() && !child.isHidden()) {
String lastEks = child.getName().toString();
StringBuilder b = new StringBuilder(lastEks);
File temp = new File(dest.toString() + "\\"
+ child.getName().toString());
if (child.getName().contains(".")) {
if (temp.exists()) {
temp = new File(dest.toString()
+ "\\"
+ b.replace(lastEks.lastIndexOf("."),
lastEks.lastIndexOf("."), " (1)")
.toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName().toString());
}
b = new StringBuilder(temp.toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName());
}
if (temp.exists()) {
for (int x = 1; temp.exists(); x++) {
if (child.getName().contains(".")) {
temp = new File(b.replace(
temp.toString().lastIndexOf(" "),
temp.toString().lastIndexOf("."),
" (" + x + ")").toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName() + " (" + x + ")");
}
}
Files.copy(child.toPath(), temp.toPath());
} else {
Files.copy(child.toPath(), temp.toPath());
}
} else if (child.isDirectory()) {
copyFile(child, dest);
}
}
}
}
features :
1. rename if file exist in the destination. example: document.doc if exist document (1).doc if exist document (2).doc if exist ...
2. copy all file from source (only file) to one folder in destination
The code below checks if the file already exists in destination, if it does, it appends #1 to file name just before the extension. If that file name also exists, it keeps appending #2,#3,#4... till the file name doesn't exist in destination. Since () and spaces create problems in Unix environment, I used # instead.
You can extend this and do a SUMCHECK if the file in destination with the identical name also has the same content and act accordingly.
Credit goes to johan indra Permana
String lastEks = file.getName().toString();
StringBuilder b = new StringBuilder(lastEks);
File temp = new File(backupDir.toString() + File.separator + file.getName().toString());
if (file.getName().contains(".")) {
if(temp.exists()) {
temp = new File(backupDir.toString() + File.separator +
b.replace(lastEks.lastIndexOf("."), lastEks.lastIndexOf("."),"#1").toString());
} else {
temp = new File(backupDir.toString() + File.separator + file.getName().toString());
}
b = new StringBuilder(temp.toString());
} else {
temp = new File(backupDir.toString() + File.separator + file.getName());
}
if (temp.exists()) {
for (int x=1; temp.exists(); x++) {
if(file.getName().contains(".")) {
temp = new File (b.replace(
temp.toString().lastIndexOf("#"),
temp.toString().lastIndexOf("."),
"#" + x ).toString());
} else {
temp = new File(backupDir.toString() + File.separator
+ file.getName() + "#" + x );
}
}
Files.copy(file.toPath(), temp.toPath());
} else {
Files.copy(file.toPath(), temp.toPath());
}
I want to transfer a folder and a subfolder using JSch ChannelSftp. I can successfully transfer files using channelsftp.put(src, dest) command but this does not work for folders (at least I could not make it work). So can someone please explain how can I transfer folders and subfolders using ChannelSftp?
To work with multilevel folder structures in jsch you:
enter them;
list their contents;
do smth with every found item;
repeat 1, 2 & 3 if subfolder is found.
DOWNLOAD dirs method inside your JSCH class:
public void downloadDir(String sourcePath, String destPath) throws SftpException { // With subfolders and all files.
// Create local folders if absent.
try {
new File(destPath).mkdirs();
} catch (Exception e) {
System.out.println("Error at : " + destPath);
}
sftpChannel.lcd(destPath);
// Copy remote folders one by one.
lsFolderCopy(sourcePath, destPath); // Separated because loops itself inside for subfolders.
}
private void lsFolderCopy(String sourcePath, String destPath) throws SftpException { // List source (remote, sftp) directory and create a local copy of it - method for every single directory.
Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(sourcePath); // List source directory structure.
for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
if (!(new File(destPath + "/" + oListItem.getFilename())).exists() || (oListItem.getAttrs().getMTime() > Long.valueOf(new File(destPath + "/" + oListItem.getFilename()).lastModified() / (long) 1000).intValue())) { // Download only if changed later.
new File(destPath + "/" + oListItem.getFilename());
sftpChannel.get(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Grab file from source ([source filename], [destination filename]).
}
} else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) {
new File(destPath + "/" + oListItem.getFilename()).mkdirs(); // Empty folder copy.
lsFolderCopy(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Enter found folder on server to read its contents and create locally.
}
}
}
REMOVE dirs method inside your JSCH class:
try {
sftpChannel.cd(dir);
Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(dir); // List source directory structure.
for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
sftpChannel.rm(dir + "/" + oListItem.getFilename()); // Remove file.
} else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) { // If it is a subdir.
try {
sftpChannel.rmdir(dir + "/" + oListItem.getFilename()); // Try removing subdir.
} catch (Exception e) { // If subdir is not empty and error occurs.
lsFolderRemove(dir + "/" + oListItem.getFilename()); // Do lsFolderRemove on this subdir to enter it and clear its contents.
}
}
}
sftpChannel.rmdir(dir); // Finally remove the required dir.
} catch (SftpException sftpException) {
System.out.println("Removing " + dir + " failed. It may be already deleted.");
}
CALL these methods from outside like:
MyJSCHClass sftp = new MyJSCHClass();
sftp.removeDir("/mypublic/myfolders");
sftp.disconnect(); // Disconnecting is obligatory - otherwise changes on server can be discarded (e.g. loaded folder disappears).
Above code(by zon) works for download as per my understanding.I need to upload to a remote server.I wrote below code to achieve the same.Please try and comment if any issue(it ignores files starting with ".")
private static void lsFolderCopy(String sourcePath, String destPath,
ChannelSftp sftpChannel) throws SftpException, FileNotFoundException {
File localFile = new File(sourcePath);
if(localFile.isFile())
{
//copy if it is a file
sftpChannel.cd(destPath);
if(!localFile.getName().startsWith("."))
sftpChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
}
else{
System.out.println("inside else "+localFile.getName());
File[] files = localFile.listFiles();
if(files!=null && files.length > 0 && !localFile.getName().startsWith("."))
{
sftpChannel.cd(destPath);
SftpATTRS attrs = null;
//check if the directory is already existing
try {
attrs = sftpChannel.stat(destPath+"/"+localFile.getName());
} catch (Exception e) {
System.out.println(destPath+"/"+localFile.getName()+" not found");
}
//else create a directory
if (attrs != null) {
System.out.println("Directory exists IsDir="+attrs.isDir());
} else {
System.out.println("Creating dir "+localFile.getName());
sftpChannel.mkdir(localFile.getName());
}
//System.out.println("length " + files.length);
for(int i =0;i<files.length;i++)
{
lsFolderCopy(files[i].getAbsolutePath(),destPath+"/"+localFile.getName(),sftpChannel);
}
}
}
}
From: http://the-project.net16.net/Projekte/projekte/Projekte/Programmieren/sftp-synchronisierung.html
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Vector;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.SftpException;
public class FileMaster {
public boolean FileAction;
public File local;
public String serverDir;
public ChannelSftp channel;
public FileMaster(boolean copyOrDelete, File local, String to, ChannelSftp channel){
this.FileAction = copyOrDelete;
this.local = local;
this.serverDir = to;
this.channel = channel;
}
/*
* If FileAction = true, the File local is copied to the serverDir, else the file is deleted.
*/
public void runMaster() throws FileNotFoundException, SftpException{
if(FileAction){
copy(local, serverDir, channel);
} else {
delete(serverDir, channel);
}
}
/*
* Copies recursive
*/
public static void copy(File localFile, String destPath, ChannelSftp clientChannel) throws SftpException, FileNotFoundException{
if(localFile.isDirectory()){
clientChannel.mkdir(localFile.getName());
GUI.addToConsole("Created Folder: " + localFile.getName() + " in " + destPath);
destPath = destPath + "/" + localFile.getName();
clientChannel.cd(destPath);
for(File file: localFile.listFiles()){
copy(file, destPath, clientChannel);
}
clientChannel.cd(destPath.substring(0, destPath.lastIndexOf('/')));
} else {
GUI.addToConsole("Copying File: " + localFile.getName() + " to " + destPath);
clientChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
}
}
/*
* File/Folder is deleted, but not recursive
*/
public void delete(String filename, ChannelSftp sFTPchannel) throws SftpException{
if(sFTPchannel.stat(filename).isDir()){
#SuppressWarnings("unchecked")
Vector<LsEntry> fileList = sFTPchannel.ls(filename);
sFTPchannel.cd(filename);
int size = fileList.size();
for(int i = 0; i < size; i++){
if(!fileList.get(i).getFilename().startsWith(".")){
delete(fileList.get(i).getFilename(), sFTPchannel);
}
}
sFTPchannel.cd("..");
sFTPchannel.rmdir(filename);
} else {
sFTPchannel.rm(filename.toString());
}
GUI.addToConsole("Deleted: " + filename + " in " + sFTPchannel.pwd());
}
}