Writing binary data to ftp location - c#

How come this code writes an empty file at given location?
No error messages.
// upload file
WebRequest upload = WebRequest.Create(ftp + path + "/" + file);
upload.Method = WebRequestMethods.Ftp.UploadFile;
upload.Credentials = new NetworkCredential(username, password);
String filePath = HttpContext.Current.Server.MapPath("~/temp/" + file); // path to file to upload
Stream myReadStream = new FileStream(filePath, FileMode.Create); // stream that can read binary data
BinaryWriter myStreamWriter = new BinaryWriter(upload.GetRequestStream()); // writer that can write the binary data to the FTP server
while (myReadStream.ReadByte() != -1)
{
myStreamWriter.Write(myReadStream.ReadByte());
}
myStreamWriter.Close();
myReadStream.Close();
Removing the while loop creates a file 4byte big and corrupt so I guess I cant get in the while loop like this.

You should call upload.GetResponse() after myStreamWriter closed.
PS: In the while you write ONE time for every TWO times read, is it really you want?

Related

I'm getting "The process cannot access the file because it is being used by another process" error. Any ideas?

So, I created a file and a txt file into the AppData, and I want to overwrite the txt. But when I try to do it, it keeps giving me that error. Any ideas?
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string setuppath = (path + "\\");
string nsetuppath = (setuppath + "newx" + "\\");
Directory.CreateDirectory(nsetuppath);
string hedef2 = (nsetuppath + "commands.txt");
File.Create(hedef2);
StreamWriter sw = new StreamWriter(hedef2); ----> This is where the error appears.
sw.WriteLine("Testtest");
Just use the using statement when using streams. The using statement automatically calls Dispose on the object when the code that is using it has completed.
//path to the file you want to create
string path = #"C:\code\Test.txt";
// Create the file, or overwrite if the file exists.
using (FileStream fs = File.Create(path))
{
byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
There are many ways of manipulate streams, keep it simple depending on your needs

FtpWebRequest - Transferring file name containing fragment marker (#)

EDIT: Not sure its the answer but it is a workaround... rather than looking at the file transfer objects I added .Replace to the FTP string and got the result I was looking for, the target file name is now matching the source file name.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name.Replace("#", "%23"));
I have an existing C# FTP process that has been in use for years. A new file naming convention was implemented that uses the # character in the actual file name. From what I can tell the # is being interpreted as a fragment marker during the file transfer resulting in an incorrect file name on the target server.
Source file name: '9300T_#Test.xml'
Target file name: '9300T_'
Is there a way to force the actual file name to be used?
When I view object values during execution I can see the original string is correct but I also see the '#Test.xml' under the Fragment property.
I've experimented with different properties of WebRequest, FtpWebRequest, and Uri. So far I have not found a combination that works and have not found a solution on the web.
I've tested using other FTP clients (DOS prompt, Mozilla) and the file is transferred correctly which leads me to believe the solution is property driven, or, it is a limitation to the objects I'm using.
Below is the code I'm testing from a windows form which produces the problem.
Thanks.
string sourcePath = #"C:\FILES\";
string sourcePattern = "9300T*.xml";
string targetServer = "test_server_name";
string targetPath = "/";
string targetLogin = "server_login";
string targetPassword = "login_password";
string[] uploadFiles = Directory.GetFiles(sourcePath, sourcePattern);
// Loop through and process the list.
foreach (string file in uploadFiles)
{
// Create the file information object.
FileInfo fileInfo = new FileInfo(file);
// Create the FTP request object.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name);
ftpRequest.Credentials = new NetworkCredential(targetLogin, targetPassword);
ftpRequest.KeepAlive = false;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.ContentLength = fileInfo.Length;
// Opens a file stream to read the file being uploaded.
FileStream readStream = fileInfo.OpenRead();
// Create the stream to which the upload file is written to.
Stream writeStream = ftpRequest.GetRequestStream(); // -- TARGET FILE IS CREATED WITH WRONG NAME AT THIS POINT
// Set the buffer size.
int bufferLength = 2048;
byte[] buffer = new byte[bufferLength];
// Read from and write to streams until content ends.
int contentLength = readStream.Read(buffer, 0, bufferLength);
while (contentLength != 0)
{
writeStream.Write(buffer, 0, contentLength);
contentLength = readStream.Read(buffer, 0, bufferLength);
}
// Flush and close the streams.
readStream.Flush();
readStream.Close();
writeStream.Flush();
writeStream.Close();
fileInfo.Delete();
}
When you are concatenating file name to create URL for web request,
you have to escape file name using percent-enconding, otherwise characters after "#" are considered to be URL fragment instead of being part of the file name.
I suggest to use function like Uri.EscapeDataString() Instead of Replace("#", "%23"), because it properly handles all other reserved characters (such as '#').
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + Uri.EscapeDataString(fileInfo.Name));
If targetPath could contain reserved characters, you may need to escape it too.

Xamarin android data saving to json file

I need to save the file when method OnDestroy is called and load same file when method OnCreate is called. At this time I can read json file easily from Assets (this works fine)
StreamReader reader = new StreamReader(Assets.Open("reiksmes.json"));
string JSONstring = reader.ReadToEnd();
Daiktai myList = JsonConvert.DeserializeObject<Daiktai>(JSONstring);
items.Add(myList);
, but I have some problems when I try to save(write) Daiktai class data to the same file I opened above. I tried:
string data = JsonConvert.SerializeObject(items);
File.WriteAllText("Assets\\reiksmes.json", data);
with this try I get error System.UnauthorizedAccessException: Access to the path "/Assets
eiksmes.json" is denied.
also tried:
string data = JsonConvert.SerializeObject(items);
StreamWriter writer = new StreamWriter(Assets.Open("reiksmes.json"));
writer.WriteLine(data);
and with this try I get error System.ArgumentException: Stream was not writable.
Summary:
I think I chose bad directory(Assets), I need to save and load data (json format). So where do I need to save them and how(give example)?
You can't save anything to assets. You can just read from it. You have to save the file to a different folder.
var fileName = "reiksmes.json";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, fileName);
Console.WriteLine(path);
if (!File.Exists(path))
{
var s = AssetManager.Open(fileName);
// create a write stream
FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
// write to the stream
ReadWriteStream(s, writeStream);
}

Creating ZIP on the fly produces corrupted file

I'm trying to make some sort of download service for a school project. Concept is simple - create a zip file from uploaded files. First problem is asp.net on school server is configured that apps cannot write any files, so I'm storing them in database. Then I need to create zip from these. Again, no writing on disk. I managed to get it to work. Almost - the code produces corrupted file.
Fun fact is that commented part produces working file. The difference is in 11th and 12th byte. It seems to be checksum or file length, but in corrupted file it is different each time.
The solution to this problem is using DotNetZip lib, but I think it is a matter of one line or something, because there are only 2 bytes wrong. (Bytes 12-15 correspond to modification date and time, so they had to be different. I'm not sure why my editor didn't show me that there's chunk of data missing at the end).
Corrupted file is missing a signature at the end. It may be caused by wrong content length header or zip generation.
using (var memoryStream = new MemoryStream())
{
// var filepath = context.Server.MapPath("files\\") + Guid.NewGuid() + ".zip";
// var zip = ZipFile.Open(filepath, ZipArchiveMode.Create);
var mzip = new ZipArchive(memoryStream, ZipArchiveMode.Create);
while (reader.Read())
{
//zip.CreateEntryFromFile((string) reader["path"], (string) reader["name"], CompressionLevel.Optimal);
var contents = (byte[]) reader["contents"];
var stream = mzip.CreateEntry((string) reader["name"], CompressionLevel.Optimal).Open();
using (var fs = new MemoryStream(contents))
{
fs.CopyTo(stream);
}
stream.Close();
}
// zip.Dispose();
Response.Clear();
Response.ContentType = "application/ocetet-stream";
Response.HeaderEncoding = Response.ContentEncoding;
Response.AppendHeader("content-disposition", "attachment; filename=\"" + gname + ".zip\"");
//Response.AppendHeader("content-length", new FileInfo(filepath).Length.ToString());
Response.AppendHeader("content-length", memoryStream.Length.ToString());
// Response.TransmitFile(filepath);
Response.BinaryWrite(memoryStream.ToArray());
Response.Flush();
}
Also - I'm new to C#, so my code may be pretty bad.

How I can display Stream on the page?

I have a WCF method that I am calling, the method suppose to create a file but it create an exception. I try to find what is in the stream request that I am passing to this method. How I can alert or write this stream so I can find the content. That is my method:
Stream UploadImage(Stream request)
{
Stream requestTest = request;
HttpMultipartParser parser = new HttpMultipartParser(request, "data");
string filePath = "";
string passed = "";
if (parser.Success)
{
// Save the file somewhere
//File.WriteAllBytes(FILE_PATH + title + FILE_EXT, parser.FileContents);
// Save the file
//SaveFile( mtp.Filename, mtp.ContentType, mtp.FileContents);
FileStream fileStream = null;
BinaryWriter writer = null;
try
{
filePath = HttpContext.Current.Server.MapPath("Uploded\\test.jpg"); // BuildFilePath(strFileName, true);
filePath = filePath.Replace("SSGTrnService\\", "");
fileStream = new FileStream(filePath, FileMode.Create);
it produces an error on this line :
fileStream = new FileStream(filePath, FileMode.Create);
that I try to understand why file can not created.
Given the information you gave, I can only assume that your code tries to create the file test.jpg somewhere where your application is not allowed to write. A common mistake would be somewhere in the Program files folder. In modern Windows versions, that is specially protected.

Categories

Resources