Has anybody used the ftp.changeWorkingDirectory command for mainframe datasets. This command returns true when there is a dataset. It also returns true when there is no dataset. Can you share any sample java ftp code if you have any that you use to deal with mainframe datasets. Here is the code I have that does not work.
public static FTPFile[] GetListOfMembersFromPDS(String pdsname, String serverN) {
FTPSClient ftp = FTPConnect(serverN);
FTPFile[] files = null;
boolean success = false;
try {
success = ftp.changeWorkingDirectory(pdsname);
if (!success) {
throw new IOException("Unable to change working directory to " + pdsname
+ " for ftp transfer with ftp client = " + ftp + ". " + ftp.getReplyString());
}
} catch (IOException e) {
e.printStackTrace();`enter code here`
}
System.out.println(success);
try {
files = ftp.listFiles();
} catch (IOException e) {
e.printStackTrace();
}
return files;
}
Changing the working directory in a z/OS dataset environment will generally return true, unless you specify a qualifier that is too long, or the whole name is too long. That does not indicated that the working directory exists or not, as mainframe datasets don't work on a directory structure.
If you change to a "working directory" that doesn't exist yet, you will get this response:
250 "THIS.IS.THE.WORKING.DIRECTOR." is the working directory name prefix.
If you try with a name that is invalid, you'll get false.
501 A qualifier in "THIS.IS.THE.WORKING.DIRECTORY" is more than 8 characters
If you try with a name that is too long, you'll get false.
501 Invalid directory name - too large.
So relying on the boolean from changeWorking Directory won't work. You'll need to look at the reply string with the "getReplyString()" method and then parse it.
A loadlib PDS will say something like
250-The working directory may be a load library
250 The working directory "GAME.LOADLIB" is a partitioned data set
A non-loadlib PDS will just say
250 The working directory "GAME.COBOL" is a partitioned data set.
listFiles, listDirectories and ListNames have different behaviours too.
I have a number of datasets which are GAME.SRCE, GAME.COPYLIB, GAME.LOADLIB and GAME.LOADLIB.PDSE. All of them are partitioned datasets. If you change directory to GAME, and do listNames(), you get all 4. If you listFiles or listDirectories, you ONLY get the COPYLIB and the SRCE. If you change directory to GAME.SRCE, then all three methods will list all the members. If you change directory to GAME.LOADLIB, then ONLY listNames will list the members. You also do not know that GAME.LOADLIB.PDSE exists.
This was done using Apache Commons, commons-net-3.6.jar and z/OS.
Here's a simple example I found by searching. You should see success=false if the directory can't be changed:
// Change working directory
success = ftp.changeWorkingDirectory(pdsname);
String[] replies = ftp.getReplyStrings();
if (replies != null && replies.length > 0) {
for (String aReply : replies) {
System.out.println("SERVER: " + aReply);
}
}
if (success) {
System.out.println("Successfully changed working directory.");
} else {
System.out.println("Failed to change working directory to " + pdsname + ". See server's reply.");
}
Related
We are currently using the EasyUpload add-on, and we have specified the criteria for this component:
a) only CSV files are allowed, with a cap size of 1MB per file.
b) only one file can be submitted at a time.
We just did an uploading test on small-sized CSV files that are below 100Kb. Usually, the upload process completes successfully. Occasionally, the error of "Could not open file, The system cannot find the file specified" is displayed although the file is already inside the temp folder, and we found that this happens either when:
a) If the same file is uploaded again after making a small change and within a few seconds after the file has been uploaded successfully.
b) If there are two tabs of the web app, logged under different users were uploading their respective csv files and they also do the same thing of changing values in the csv before uploading them again.
We tried forcing the file upload through (as another testing method) and noticed after a while that the files sometimes get stuck in the queue although we have imposed a one file at a submission time rule. It was displayed in a message "There are too many files over the count limit". We also considered of putting a sleep / wait command of 3-5 seconds after the file submission.
MultiFileUpload multiFileUpload = new MultiFileUpload() {
#Override
protected void handleFile(File tmpFile, String fileName, String mimeType, long length) {
String[] header = {"EOD_NUM","OUTLET_NAME","POSM_NAME","EOD_DATE","TOTAL_SALES","GROSS_SALES",
"TRAN_COUNT","VOID_COUNT","SERVICE_CHARGE","DISCOUNT_AMT","VAT_TAX_AMT","SVC_TAX_AMT","ROUNDING_ADJ"};
uploadLogger.debug("File: " + tmpFile.getAbsolutePath());
uploadLogger.debug("FileName: " + fileName);
uploadLogger.debug("MimeType: " + mimeType);
uploadLogger.debug("File Length: " + length);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyyyyHHmmss");
LocalDateTime now = LocalDateTime.now();
File f2 = null;
f2 = new File(busId+"_"+dtf.format(now)+".csv");
tmpFile.renameTo(f2);
try {
///var/lib/tomcat8/ in linux
///D:\\home\\site\\wwwroot\\ in Windows
uploadLogger.debug("f2 absolutepath: " + f2.getAbsolutePath());
uploadLogger.debug("f2 canonical path: " + f2.getCanonicalPath());
CloudBlockBlob blob = container.getBlockBlobReference(f2.getName());
if(f2.length() > 0){
blob.uploadFromFile(f2.getAbsolutePath());
Notification.show("File upload completed.",Notification.Type.TRAY_NOTIFICATION);
}
CSVReader reader = new CSVReader(new FileReader(f2.getAbsolutePath()), ',' , '"' , 0);
//read header name
//String[] myheader = reader.readNext();
//NOTE :: Store all row and column from csv info List of String Array
myEntries = reader.readAll();
if (myEntries != null && !myEntries.isEmpty()) {
boolean success = uploadDAO.insertUploaderEntry(myEntries,busId, userId,"");
uploadLogger.debug("SUCCESSS??? " + success);
if(success){
Notification successNotify = new Notification("Record has been created successfully.","Upload Successful!");
successNotify.setDelayMsec(3000);
successNotify.setStyleName(ValoTheme.NOTIFICATION_SUCCESS);
successNotify.setPosition(Position.MIDDLE_CENTER);
successNotify.show(Page.getCurrent());
}else {
Notification.show("Error in submitting uploaded record.","Upload failed!"
, Notification.Type.ERROR_MESSAGE).setDelayMsec(3000);
}
Thread.sleep(3000); //added to see if the delay solves the problem or not.
}
} catch (URISyntaxException | StorageException | IOException ex) {
new Notification("Could not open file",ex.getMessage(),Notification.Type.ERROR_MESSAGE).show(Page.getCurrent());
uploadLogger.debug(ex);
} catch (InterruptedException ix) {
uploadLogger.debug("Interrupted Exception found: " + ix.getMessage());
}
}
#Override
protected boolean supportsFileDrops() {
return false;
}
};
multiFileUpload.setMaxFileCount(1);
multiFileUpload.setUploadButtonCaption("Upload CSV file here");
multiFileUpload.setMaxFileSize(fileSizeLimit); // 2MB
multiFileUpload.setAcceptFilter(".csv");
We are unsure whether if this problem is a known limitation of the component or not.
Some of the questions we have discovered along the way are:
a) Is there a better way or to control on the file uploading and to avoid the open file / file not found error?
b) Are the values in the setAcceptedFilter method the mime/type values or something else. We noticed for images, it's "images/*" but for csv, we had to put in as ".csv"
Answering to your second question. The acceptFilter is directly passed to upload inputs "accept" attribute, so both .csv and text/csv should do fine. See https://www.w3schools.com/tags/att_input_accept.asp for more instructions.
I am trying to access a file in remote shared location.
////hostname//data//upload//123//test.txt
File sourceFile=new File("////hostname//data//upload//123//test.txt");
sysout("sourceFile.exists()"+sourceFile.exists())//returning false
If a directory is empty file.exists() is returning true.
I am using Java 1.6
I don't understand what is this weird behavior.
First of all to come back to Erwin´s suggestion, this is not the right attempt. The character \ is used in Java as an escape sequence, usually to print out reserved characters. For example will
String s = "The weather is really "nice" today";
result in an error, as " is already reserved for strings. The correct version would be
String s = "The weather is really \"nice\" today";
Coming back to the question, you have to know that when you create a file and test if it exists Java will validate the abstract pathname of the file. That said, if your abstact path is a directory and it exists true will be returned.
Edit:
If you intend to check if an abstract pathname is a directory try the following:
// Check if a file is a directory
if(file.isDirectory()) {
}
// Check if a file contains something
if(file.list().length > 0) {
}
Check this example ,it checks the directory else creates a new one then your new file created.
File f = new File("D:/image_send");
File file = new File("D:/image_send/" + date + ".txt");
try {
if(!f.isDirectory()){
f.mkdirs();
}
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("File created Success");
public static boolean fileTransfer(String src, String des) throws Exception {
if (des == null || des.equals("") || src == null || src.equals("")) {
return false;
}
File fileExisting = new File(src);
File fileNew = new File(des+ fileExisting.getName());
if (fileExisting.exists() && !fileExisting.isDirectory()) {
if (fileExisting.renameTo(fileNew)) {
System.out.println("File is moved successful!");
} else {
System.out.println("File is failed to move!");
}
}
return fileNew.exists();
}
This is the code for file transfer as per your comment ,use src as sourcepath and des as destination path if you get a boolean false,that means path given is wrong.
Pretty self-explanatory title. I'm using Google Drive Client Api for Java. What I currently have is as follows:
File f = mService.files.get(fileId).execute();
However, I can't find the property in File used to check if a file is trashed or not. File.getExplicitlyTrashed() gives me null for both trashed and not trashed files.
The trashed property is hidden inside the File.Labels class, which you can get from File.getLabels(). A working example is:
public boolean validFileId(String id) {
try {
File f = mService.files().get(id).execute();
return !f.getLabels().getTrashed();
} catch (IOException e) {
e.printStackTrace();
System.out.println("bad id: " + id);
}
return false;
}
I have the following function inside a Stateless EJB running in Glassfish. All it does is write some data to a file. The first part of the function just creates the path to where the file needs to go. The second part actually writes the file.
private boolean createFile(String companyName, String fileName, byte[] data)
{
logger.log(Level.FINEST, "Creating file: {0} for company {1}", new Object[]{fileName, companyName});
File companyFileDir = new File(LOCAL_FILE_DIR, companyName);
if(companyFileDir.exists() == false)
{
boolean createFileDir = companyFileDir.mkdirs();
if(createFileDir == false)
{
logger.log(Level.WARNING, "Could not create directory to place file in");
return false;
}
}
File newFile = new File(companyFileDir, fileName);
try
{
FileOutputStream fileWriter = new FileOutputStream(newFile);
fileWriter.write(data);
}
catch(IOException e)
{
logger.log(Level.SEVERE,"Could not write file to disk",e);
return false;
}
logger.log(Level.FINEST,"File successfully written to file");
return true;
}
The output I get after this code executes is:
WARNING: Could not create directory to place file in
So obviously Glassfish cant create this directory. I am am assuming this has something to do with permissions. Can anyone give me a direction to go as to what might be wrong here?
I am running this on Glassfish 3.12 on Ubuntu 12
different things:
1) Compare spec: (21.1.2 Programming Restrictions)
An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.
I'm sure GF isn't enforcing this, but you should be aware of that.
2) The code itself is fine. Try chmod +777 on the LOCAL_FILE_DIR to get an idea if it has to do with rights in general ...
Hope that helps ...
I'm currently using a Java FTP library (ftp4j) to access a FTP server. I want to do a file count and directory count for the server, but this means I would need to list files within directories within directories within directories, etc.
How is this achievable? Any hints would be greatly appreciated.
Extract from the code:
client = new FTPClient();
try {
client.connect("");
client.login("", "");
client.changeDirectory("/");
FTPFile[] list = client.list();
int totalDIRS = 0;
int totalFILES = 0;
for (FTPFile ftpFile : list) {
if (ftpFile.getType() == FTPFile.TYPE_DIRECTORY) {
totalDIRS++;
}
}
message =
"There are currently " + totalDIRS + " directories within the ROOT directory";
client.disconnect(true);
} catch (Exception e) {
System.out.println(e.toString());
}
Make a recursive function that given a file that might be a directory returns the number of files and directories in it. Use isDir and listFiles.
Try using recursive functions.
This is could be a function that checks a directory for files, then you can do a check if a file has a child, that would be a directory.
If it has a child you can call that same function again for that directory, etc.
Like this pseudo java here:
void Function(String directory){
... run through files here
if (file.hasChild())
{
Function(file.getString());
}
}
I'm sure you can use that kind of coding in counting the files as well...
Just use a recursive function like below.
Note that my code uses Apache Commons Net, not ftp4j, what the question is about. But the API is pretty much the same and ftp4j seems to be an abandoned project now anyway.
private static void listFolder(FTPClient ftpClient, String remotePath) throws IOException
{
System.out.println("Listing folder " + remotePath);
FTPFile[] remoteFiles = ftpClient.listFiles(remotePath);
for (FTPFile remoteFile : remoteFiles)
{
if (!remoteFile.getName().equals(".") && !remoteFile.getName().equals(".."))
{
String remoteFilePath = remotePath + "/" + remoteFile.getName();
if (remoteFile.isDirectory())
{
listFolder(ftpClient, remoteFilePath);
}
else
{
System.out.println("Foud remote file " + remoteFilePath);
}
}
}
}