Java FTPClient for Mainframe GDG - ftp-client

I'm trying to transfer file to Mainframe using Java FTPClient.Below code works for normal datasets in mainframe. But when i try to transfer file to mainframe GDG (Generation Data Groups) like 'FTPAA.TEST.BBBB.DLY(+1)'. Its not working. Is there any specific settings need to do in FTPClient to transfer file to GDG or am i missing any configurations?
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
......
File file = new File("abc.csv");
String testName = "FTPAA.TEST";
fis = new FileInputStream(file);
// Upload file to the ftp server
try{
result = ftpclient.storeFile(testName, fis);
}

Related

The specified share already exists on Azure Storage File Shares

I am using "Azure Storage File Shares" to store some files from our website, but failed with error message "The specified share already exists".
I have change the file that being upload, but the error persist.
Here my code
public static void Test2Upload()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
string connectionString = "DefaultEndpointsProtocol=https;AccountName=xxxxx;AccountKey=xxxxx;EndpointSuffix=core.windows.net";
string shareName = "myapp-dev";
string dirName = "files";
string fileName = "catto.jpg";
// Path to the local file to upload
string localFilePath = #"d:\temp\two.jpg";
// Get a reference to a share and then create it
ShareClient share = new ShareClient(connectionString, shareName);
share.Create();
// Get a reference to a directory and create it
ShareDirectoryClient directory = share.GetDirectoryClient(dirName);
directory.Create();
// Get a reference to a file and upload it
ShareFileClient file = directory.GetFileClient(fileName);
using (FileStream stream = File.OpenRead(localFilePath))
{
file.Create(stream.Length);
file.UploadRange(
new HttpRange(0, stream.Length),
stream);
}
}
Looks like I should not create ShareClient with same name several times.
Then how to check and use it?
The most important question is, why the file still not yet uploaded (even if I rename the ShareClient object)?
Looks like I should not create ShareClient with same name several
times. Then how to check and use it?
You can use ShareClient.CreateIfNotExists instead of ShareClient.Create method. Former will try to create a share but if a share already exists, then it won't be changed.
You can also use ShareClient.Exists to check if the share exists and then create it using ShareClient.Create if it does not exist. This is not recommended however as it might not work if multiple users are executing that code at the same time. Furthermore, you will be making 2 network calls - first to check the existence of share and then the second to create it.
The most important question is, why the file still not yet uploaded
(even if I rename the ShareClient object)?
Your code for uploading the file looks ok to me. Are you getting any error in that code?
We could use ShareClient.CreateIfNotExists when creating ShareClient object to avoid the problem. Like below
ShareClient share = new ShareClient(connectionString, shareName);
share.CreateIfNotExists();
You might found Similar problem on ShareDirectoryClient.
This part purpose is to create the folder structure.
The upload will fail if the destination folder is not exist.
Error will occur if we create a folder when it already exist.
So, use method ShareDirectoryClient.CreateIfNotExists, like below
ShareDirectoryClient directory = share.GetDirectoryClient(dirName);
directory.CreateIfNotExists();
Here my complete code
public static void TestUpload()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
string connectionString = "DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=xx;EndpointSuffix=core.windows.net";
string shareName = "myapp-dev";
string dirName = "myfiles";
string fileName = "catto.jpg";
string localFilePath = #"d:\temp\two.jpg";
// Get a reference to a share and then create it
ShareClient share = new ShareClient(connectionString, shareName);
share.CreateIfNotExists();
// Get a reference to a directory and create it
ShareDirectoryClient directory = share.GetDirectoryClient(dirName);
directory.CreateIfNotExists();
// Get a reference to a file and upload it
ShareFileClient file = directory.GetFileClient(fileName);
using (FileStream stream = File.OpenRead(localFilePath))
{
file.Create(stream.Length);
file.UploadRange(
new HttpRange(0, stream.Length),
stream);
}
}

File write permission in Azure Function App

I am using Azure Function App
I am using CSVHelper package to create file, But CSVHelper needs local file path first to Create/Write file.
using (var writer = new StreamWriter(filePath))
using (var csvData = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// Write input in csv
csvData.WriteRecords(input);
}
What path can I use to create file in Azure Function App?
Since it looks like you're using a StreamWriter, you could also write to a MemoryStream instead of creating an actual file. This feels like a better route to take with Azure Functions.
If you're really set on creating an actual file, you can do so by using System.IO.Path.GetTempPath(), which will always return a valid path for any given system. Create your temporary file there, then continue with the process.
Please take into account that your Function might run multiple times on the same environment, so be sure to use a unique filename.
For future reference:
private static void ExportContentToCsv(ILogger log, IEnumerable<T> content)
{
var path = Path.Combine(Path.GetTempPath(), "content.csv");
log.LogInformation($"Writing csv file at {path}");
if (File.Exists(path))
{
log.LogInformation("Deleting existent resources...");
File.Delete(path);
}
using (var writer = new StreamWriter(path))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(content);
}
}
}

Copying files from FTP to Azure Blob Storage

I have created my FTP (ftp://xyz.in) with user id and credentials.
I have created an asp.net core API application that will copy files from FTP to Azure blob storage.
I have my API solution placed in C://Test2/Test2 folder.
Now below is my code :
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp:/xyz.in");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("pqr#efg.com", "lmn");
// Copy the contents of the file to the request stream.
byte[] fileContents;
// Getting error in below line.
using (StreamReader sourceStream = new StreamReader("ftp://xyz.in/abc.txt"))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine($"Upload File Complete, status {response.StatusDescription}");
}
But on line
using (StreamReader sourceStream = new StreamReader("ftp://xyz.in/abc.txt"))
I am getting error : System.IO.IOException: 'The filename, directory name, or volume label syntax is incorrect : 'C:\Test2\Test2\ftp:\xyz.in\abc.txt''
I am not able to understand from where does 'C:\Test2\Test2' string gets append to my FTP.
Test2 is a folder where my .Net Core application is placed.
StreamReader() doesn't take a URL/URI, it takes a file path on your local system: (read the doco):
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.-ctor?view=net-5.0
StreamReader is interpurting the string you've supplied as a filename ("ftp://xyz.in/abc.txt"), and it's looking for it in the current running folder "C:\Test2\Test2". If your string was "abc.txt", it would look for a file called "abc.txt" in the current folder, e.g. C:\Test2\Test2\abc.txt.
What you want is to get the file using WebClient or something similar:
WebClient request = new WebClient();
string url = "ftp://xyz.in/abc.txt";
request.Credentials = new NetworkCredential("username", "password");
try
{
byte[] fileContents = request.DownloadData(url);
// Do Something...
}

Excel OpenXML, OleDB and "External table is not in the expected format" error

I am generating Excel files using OpenXML, the file opens without any issues on my desktop with Excel 2016 installed. The file also passes validation using Open XML Productivity Tool 2.5.
The problem is that the file is rejected from the SQL Server Integration Services (SSIS) processing. The error is "External table is not in the expected format"
As far as I know SSIS is using OLEDB to process the files.
I have tried to read the file locally using the following code and was able to reproduce the same error.
The code is as follows:
var fileName = "C:\\Temp\\myExcel.xlsx";
var connectionString = String.Empty;
if (Path.GetExtension(fileName) == ".xlsx")
{
connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;\"", fileName);
}
else //.xls
{
connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"", fileName);
}
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
var adapter = new OleDbDataAdapter("select * from [test$]", conn);
var excelDataSet = new DataSet();
adapter.Fill(excelDataSet, "anyNameHere");
var data = excelDataSet.Tables["anyNameHere"];
foreach (DataRow row in data.Rows)
{
Console.Out.WriteLine(row[NAME].ToString());
}
}
All I was able to find in the net that this error is due to wrong connection string (Microsoft.Jet.OLEDB.4.0 and Excel 8.0 instead of Microsoft.ACE.OLEDB.12.0 and Excel 12.0) but I already have this.
This is definitely something wring with the file itself. The problem disappears if I open the file in Excel, and use save as.
I was trying to unpack the original and resaved files and compare the contents but the difference is huge, when saving excel adds lots of styles, themes, and xmls references. I really would not like to follow that path.
Do you know what parts are important for OleDB provider when reading Excel??

Upload a file to a document library in SharePoint 2010 programmatically in client-server application

I am using below code to upload the file in SharePoint 2010 Library
String fileToUpload = #"C:\YourFile.txt";
String sharePointSite = "http://yoursite.com/sites/Research/";
String documentLibraryName = "Shared Documents";
using (SPSite oSite = new SPSite(sharePointSite))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
if (!System.IO.File.Exists(fileToUpload))
throw new FileNotFoundException("File not found.", fileToUpload);
SPFolder myLibrary = oWeb.Folders[documentLibraryName];
// Prepare to upload
Boolean replaceExistingFiles = true;
String fileName = System.IO.Path.GetFileName(fileToUpload);
FileStream fileStream = File.OpenRead(fileToUpload);
// Upload document
SPFile spfile = myLibrary.Files.Add(fileName, fileStream, replaceExistingFiles);
// Commit
myLibrary.Update();
}
}
This worked well through my machine. But when I deploy it on server and used the below snippet to upload file in library from my machine, it gives error. It is not getting the file location (C:\YourFile.txt) from local(client) machine.
When you run on the server your code runs under a different account (apppool identity) which does not have the permission to read C drive.
I dont know why would you want to read and upload a file from the same server, looks like you are simply testing Sharepoint Object Model then it is ok
If you are expecting some other app or service to keep an updated file for Sharepoint , it should be moved to the web directory i.e \wwwroot\wss\VirtualDirectories\80 and then use your code to read and update your doc lib (myLibrary) as you are doing.
Are you running this in a console app or "in SharePoint"?
Could it be that the account running the code doesnt have read permissions in C:\?

Resources