I'm trying to retrieve an image saved in postgresql database in BYTEA format, but I'm having difficulties in transforming the byte array to image using C#. I'm getting "INVALID PARAMETERS" as a return. I've been trying for days and still haven't been able to. Can anyone help me?
byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
try
{
using (MemoryStream mStream = new MemoryStream(byteArrayIn))
{
return Image.FromStream(mStream);
}
}
catch (Exception)
{
throw;
}
}
private void dgv_empresa_CellClick(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32(dgv_empresa.SelectedCells[0].OwningRow.Cells[9].Value);
if (id != 0)
{
try
{
string query = " SELECT p.photo_img " +
" FROM empresa as e, photo as p " +
" WHERE e.empresa_img = " + id + " AND " +
" e.empresa_img = p.photo_id; ";
conexao.Open();
dgv_empresa.Rows.Clear();
DataTable dados = new DataTable();
NpgsqlDataAdapter adaptador = new NpgsqlDataAdapter(query, conexao);
adaptador.Fill(dados);
Image imagem = null;
if (dados.Rows.Count > 0)
{
foreach (DataRow linha in dados.Rows)
{
byte[] binary = ObjectToByteArray(linha[0]);
MemoryStream ms = new MemoryStream(binary, 0, binary.Length);
ms.Position = 0;
imagem = Image.FromStream(ms, true);
Image i = byteArrayToImage(binary);
}
}
pct_Imagem.Image = imagem;
}
catch (Exception ex)
{
conexao.Close();
MessageBox.Show(ex.Message, "Erro no Banco de Dados!", MessageBoxButtons.OK, MessageBoxIcon.Error);
//dgv_empresa.Rows.Clear();
}
finally
{
conexao.Close();
}
}
I am trying to Copy a TXT File in Assets over to the SD Card / Internal Storage.
All examples are in Java, is there anyway this can be done in C#?
Java Code:
final static String TARGET_BASE_PATH = "/sdcard/appname/voices/";
private void copyFilesToSdCard() {
copyFileOrDir(""); // copy all files in assets folder in my project
}
private void copyFileOrDir(String path) {
AssetManager assetManager = this.getAssets();
String assets[] = null;
try {
Log.i("tag", "copyFileOrDir() "+path);
assets = assetManager.list(path);
if (assets.length == 0) {
copyFile(path);
} else {
String fullPath = TARGET_BASE_PATH + path;
Log.i("tag", "path="+fullPath);
File dir = new File(fullPath);
if (!dir.exists() && !path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
if (!dir.mkdirs())
Log.i("tag", "could not create dir "+fullPath);
for (int i = 0; i < assets.length; ++i) {
String p;
if (path.equals(""))
p = "";
else
p = path + "/";
if (!path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
copyFileOrDir( p + assets[i]);
}
}
} catch (IOException ex) {
Log.e("tag", "I/O Exception", ex);
}
}
private void copyFile(String filename) {
AssetManager assetManager = this.getAssets();
InputStream in = null;
OutputStream out = null;
String newFileName = null;
try {
Log.i("tag", "copyFile() "+filename);
in = assetManager.open(filename);
if (filename.endsWith(".jpg")) // extension was added to avoid compression on APK file
newFileName = TARGET_BASE_PATH + filename.substring(0, filename.length()-4);
else
newFileName = TARGET_BASE_PATH + filename;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", "Exception in copyFile() of "+newFileName);
Log.e("tag", "Exception in copyFile() "+e.toString());
}
}
How would the above code be done in C#?
Thanks.
A possible solution could look like my method to copy a database from the Assets folder to the device:
public static async Task CopyDatabaseAsync(Activity activity)
{
var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "YOUR_DATABASENAME");
if (!File.Exists(dbPath))
{
try
{
using (var dbAssetStream = activity.Assets.Open("YOUR_DATABASENAME"))
using (var dbFileStream = new FileStream(dbPath, FileMode.OpenOrCreate))
{
var buffer = new byte[1024];
int b = buffer.Length;
int length;
while ((length = await dbAssetStream.ReadAsync(buffer, 0, b)) > 0)
{
await dbFileStream.WriteAsync(buffer, 0, length);
}
dbFileStream.Flush();
dbFileStream.Close();
dbAssetStream.Close();
}
}
catch (Exception ex)
{
//Handle exceptions
}
}
}
You can call it in OnCreate with ContinueWith
CopyDatabaseAsync().ContinueWith(t =>
{
if (t.Status != TaskStatus.RanToCompletion)
return;
//your code here
});
So, I am trying to send an image between the server and client, however, somehow when the server receives the image, the image does not render all of it.
Client Side code:
//button click
Bitmap tImage = new Bitmap(#"C:\Users\Milan\Downloads\guitarstill.gif");
byte[] bStream;
//if (string.IsNullOrEmpty(tbPayload.Text)) return;
try
{
bStream = imageToByteArray(tImage);
if (mTcpClient != null)
{
if (mTcpClient.Client.Connected)
{
mTcpClient.GetStream().BeginWrite(imageToByteArray(tImage), 0, imageToByteArray(tImage).Length, onCompleteWriteToServer, mTcpClient);
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
//Within another method:
public byte[] imageToByteArray(System.Drawing.Image imageIn) {
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
//richTextBox1.Text = ms.ToArray().ToString();
return ms.ToArray();
}
Server Side Code:
void onCompleteReadFromTCPClientStream(IAsyncResult iar)
{
TcpClient tcpc;
int nCountReadBytes = 0;
string strRecv;
ClientNode cn = null;
try
{
lock (mlClientSocks)
{
tcpc = (TcpClient)iar.AsyncState;
cn = mlClientSocks.Find(x => x.strId == tcpc.Client.RemoteEndPoint.ToString());
nCountReadBytes = tcpc.GetStream().EndRead(iar);
if (nCountReadBytes == 0)// this happens when the client is disconnected
{
MessageBox.Show("Client disconnected.");
mlClientSocks.Remove(cn);
lbClients.Items.Remove(cn.ToString());
return;
}
strRecv = Encoding.ASCII.GetString(cn.Rx, 0, nCountReadBytes);
//strRecv = Encoding.ASCII.GetString(mRx, 0, nCountReadBytes);
if (strRecv.StartsWith("GIF"))
{
//MemoryStream ms = new MemoryStream(cn.Rx);
//Image x = (Bitmap)((new ImageConverter()).ConvertFrom(cn.Rx));
pictureBox1.Image = byteArrayToImage(cn.Rx);
/*
lock (mlClientSocks)
{
//if (cn != null && cn.tclient != null && cn.tclient.Client.Connected)
//{
//foreach (var clients in spectatorsIPAndPort)
//{
cn = mlClientSocks.Find(x => x.strId == clients);
cn.Tx = new byte[512];
cn.Tx = Encoding.ASCII.GetBytes(strRecv);
cn.tclient.GetStream().BeginWrite(cn.Tx, 0, cn.Tx.Length, onCompleteWriteToClientStream, cn.tclient);
//Console.WriteLine("Sent Number of Clients via Request: " + Encoding.UTF8.GetString(cn.Tx) + " To " + clients);
//}
//}
}
*/
//printLine(DateTime.Now + " - " + cn.ToString() + ": " + strRecv);
}
cn.Rx = new byte[512];
tcpc.GetStream().BeginRead(cn.Rx, 0, cn.Rx.Length, onCompleteReadFromTCPClientStream, tcpc);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
lock (mlClientSocks)
{
printLine("Client disconnected: " + cn.ToString());
mlClientSocks.Remove(cn);
lbClients.Items.Remove(cn.ToString());
}
}
}
//within another method
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn, 0, byteArrayIn.Length);
//ms.Position = 0;
Image returnImage = Image.FromStream(ms);
return returnImage;
}
My Output:
Expected output: - this full image
I use this code
// background.js
chrome.runtime.sendNativeMessage( "com.example.native",
{ text: "test" },
function(response) {
console.log("Received " + response);
});
C# code
private static void OpenStandardStreamOut(string stringData)
{
string msgdata = "{\"text\":\"" + stringData + "\"}";
int DataLength = msgdata.Length;
Stream stdout = Console.OpenStandardOutput();
stdout.WriteByte((byte)((DataLength >> 0) & 0xFF));
stdout.WriteByte((byte)((DataLength >> 8) & 0xFF));
stdout.WriteByte((byte)((DataLength >> 16) & 0xFF));
stdout.WriteByte((byte)((DataLength >> 24) & 0xFF));
Console.Write(msgdata);
}
private static List<LoginPack> OpenStandardStreamIn()
{
Stream stdin = Console.OpenStandardInput();
int length = 0;
byte[] bytes = new byte[4];
stdin.Read(bytes, 0, 4);
length = System.BitConverter.ToInt32(bytes, 0);
string input = "";
for (int i = 0; i < length; i++)
{
input += (char)stdin.ReadByte();
}
JObject Read=(JObject)JsonConvert.DeserializeObject<JObject>(input);
//string dataPackStr = JsonConvert.SerializeObject(Read);
Chrome chromeClass = new Chrome();
List<LoginPack> lp = new List<LoginPack>();
if (Read!=null)
if (Read.Count != 0)
lp = chromeClass.getInfoFromChrome(Read["text"].ToString());
if (lp.Count == 0)
return null;
return lp;
}
//class chrome
public class Chrome
{
public class Data
{
public string key { get; set; }
public string value { get; set; }
}
public List<LoginPack> getInfoFromChrome(string colName)
{
try
{
// string filename = "my_chrome_passwords.html";
// StreamWriter Writer = new StreamWriter(filename, false, Encoding.UTF8);
string db_way = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
+ "/Google/Chrome/User Data/Profile 1/Login Data1";
Console.WriteLine("DB file = " + db_way);
string db_field = "logins";
List<LoginPack> lp = new List<LoginPack>();
byte[] entropy = null;
string description;
string ConnectionString = "data source=" + db_way + ";New=True;UseUTF16Encoding=True";
DataTable DB = new DataTable();
string sql = string.Format("SELECT * FROM {0} where action_url=\"{1}\" or origin_url=\"{2}\"", db_field, colName, colName);
// System.IO.StreamWriter file1 = new System.IO.StreamWriter("c:\\test.txt");
// file1.WriteLine(sql);
// file1.Close();
using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
{
SQLiteCommand command = new SQLiteCommand(sql, connect);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
adapter.Fill(DB);
int rows = DB.Rows.Count;
for (int i = 0; i < rows; i++)
{
byte[] byteArray = (byte[])DB.Rows[i][5];
byte[] decrypted = DPAPI.Decrypt(byteArray, entropy, out description);
lp.Add(new LoginPack { userNameElement = (string)DB.Rows[i][2], userName = (string)DB.Rows[i][3], passElement = (string)DB.Rows[i][4], pass = new UTF8Encoding(true).GetString(decrypted) });
//System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test2.txt");
//file.WriteLine(lp[i].userName);
//file.Close();
}
}
// Writer.Close();
return lp;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
ex = ex.InnerException;
return null;
}
}
}
Application(C#) give data from extension but Extension cant get any response from app
if I use OpenStandardStreamOut function at first(in C# app) then Extension can get response from it
what's the problem?
I think your 'Chrome' class is working badly. Check that again and make sure to use Standard Streams instead of your third party Streams. Also remove Console.WriteLine("DB file = " + db_way); line and try again.
I have searched the web, and is new to this still. Please have some patience with me.
What I want to do is this:
- I have a TreeView called "treeTO".
- I connect to my FTP Server and I want to populate everything here (the directories, sub directories, and the files, whatever it may be) in the treeview.
- This is my code I have so far:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ActiveServer.Server + "/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(ActiveServer.UserName, ActiveServer.Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
-This returns me the following text: Logs, Data, and WwwRoot.
I struggle to add this to the treeview and then loop through the folders to add everything to the treeview.
So here´s my working Solution for you!
Of course you have to replace the Value of "root" with the rootURL of your FTP-Server and in the Method GetWebRequest() replace "username" and "password" with your Credentials!
You need this Class to Hold Details
public class FTPListDetail
{
public bool IsDirectory
{
get
{
return !string.IsNullOrWhiteSpace(Dir) && Dir.ToLower().Equals("d");
}
}
internal string Dir { get; set; }
public string Permission { get; set; }
public string Filecode { get; set; }
public string Owner { get; set; }
public string Group { get; set; }
public string Name { get; set; }
public string FullPath { get; set; }
}
and here is the Code-Behind for your WinForm-App
private void button1_Click(object sender, EventArgs e)
{
var root = "ftp://ftp.yourFTPServer.at";
treeView1.Nodes.Clear();
treeView1.Nodes.Add(CreateDirectoryNode(root, "root"));
}
private TreeNode CreateDirectoryNode(string path, string name)
{
var directoryNode = new TreeNode(name);
var directoryListing = GetDirectoryListing(path);
var directories = directoryListing.Where(d => d.IsDirectory);
var files = directoryListing.Where(d => !d.IsDirectory);
foreach (var dir in directories)
{
directoryNode.Nodes.Add(CreateDirectoryNode(dir.FullPath, dir.Name));
}
foreach (var file in files)
{
directoryNode.Nodes.Add(new TreeNode(file.Name));
}
return directoryNode;
}
public IEnumerable<FTPListDetail> GetDirectoryListing(string rootUri)
{
var CurrentRemoteDirectory = rootUri;
var result = new StringBuilder();
var request = GetWebRequest(WebRequestMethods.Ftp.ListDirectoryDetails, CurrentRemoteDirectory);
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
if (string.IsNullOrEmpty(result.ToString()))
{
return new List<FTPListDetail>();
}
result.Remove(result.ToString().LastIndexOf("\n"), 1);
var results = result.ToString().Split('\n');
string regex =
#"^" + //# Start of line
#"(?<dir>[\-ld])" + //# File size
#"(?<permission>[\-rwx]{9})" + //# Whitespace \n
#"\s+" + //# Whitespace \n
#"(?<filecode>\d+)" +
#"\s+" + //# Whitespace \n
#"(?<owner>\w+)" +
#"\s+" + //# Whitespace \n
#"(?<group>\w+)" +
#"\s+" + //# Whitespace \n
#"(?<size>\d+)" +
#"\s+" + //# Whitespace \n
#"(?<month>\w{3})" + //# Month (3 letters) \n
#"\s+" + //# Whitespace \n
#"(?<day>\d{1,2})" + //# Day (1 or 2 digits) \n
#"\s+" + //# Whitespace \n
#"(?<timeyear>[\d:]{4,5})" + //# Time or year \n
#"\s+" + //# Whitespace \n
#"(?<filename>(.*))" + //# Filename \n
#"$"; //# End of line
var myresult = new List<FTPListDetail>();
foreach (var parsed in results)
{
var split = new Regex(regex)
.Match(parsed);
var dir = split.Groups["dir"].ToString();
var permission = split.Groups["permission"].ToString();
var filecode = split.Groups["filecode"].ToString();
var owner = split.Groups["owner"].ToString();
var group = split.Groups["group"].ToString();
var filename = split.Groups["filename"].ToString();
myresult.Add(new FTPListDetail()
{
Dir = dir,
Filecode = filecode,
Group = group,
FullPath = CurrentRemoteDirectory + "/" + filename,
Name = filename,
Owner = owner,
Permission = permission,
});
};
return myresult;
}
}
}
private FtpWebRequest GetWebRequest(string method, string uri)
{
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return null;
}
var reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
reqFTP.Method = method;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential("yourUser", "yourPassword");
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
return reqFTP;
}
There is a reason why no FTP client on the planet preemptively populates a treeview on an FTP server or displays file icons in the treeview. Either one of these will take FOREVER.
What you'll need to do is rethink how you are doing this. When you first connect you are going to want to just populate the tree up until the initial dir and then the initial directory. You do NOT want to put files in your tree view because that will also eat up too much memory in many real world situations. Just add folders (and use the same ICON for >99% of those).
This is what it should look like when you first log in:
/
-home
-joe
-public_html
-docs
-uploads
Notice that, '/' and 'home' are not fully read at this point, we just insert them as placeholders for the user to click on. After that, you just want to add the directories in the clicked folder which aren't there each time the users clicks a folder.
This strategy is going to make life a million times easier. Even if you want to try those more complicated ways to handle this you'll want to start out with the basics.
I used this class
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
namespace Backup_service
{
internal class Ftp_Client
{
//поля
//поле для хранения имени фтп-сервера
private string _Host;
//поле для хранения логина
private string _UserName;
//поле для хранения пароля
private string _Password;
//объект для запроса данных
private FtpWebRequest ftpRequest;
//объект для получения данных
private FtpWebResponse ftpResponse;
//флаг использования SSL
private bool _UseSSL = false;
//фтп-сервер
public string Host
{
get
{
return _Host;
}
set
{
_Host = value;
}
}
//логин
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
//пароль
public string Password
{
get
{
return _Password;
}
set
{
_Password = value;
}
}
//Для установки SSL-чтобы данные нельзя было перехватить
public bool UseSSL
{
get
{
return _UseSSL;
}
set
{
_UseSSL = value;
}
}
//Реализеум команду LIST для получения подробного списока файлов на FTP-сервере
public FileStruct[] ListDirectory(string path)
{
if (path == null || path == "")
{
path = "/";
}
//Создаем объект запроса
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
//логин и пароль
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
//команда фтп LIST
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
ftpRequest.EnableSsl = _UseSSL;
//Получаем входящий поток
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
//переменная для хранения всей полученной информации
string content = "";
StreamReader sr = new StreamReader(ftpResponse.GetResponseStream(), System.Text.Encoding.ASCII);
content = sr.ReadToEnd();
sr.Close();
ftpResponse.Close();
DirectoryListParser parser = new DirectoryListParser(content);
return parser.FullListing;
}
//метод протокола FTP RETR для загрузки файла с FTP-сервера
public void DownloadFile(string path, string currentfileName)
{
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
//команда фтп RETR
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpRequest.EnableSsl = _UseSSL;
//Файлы будут копироваться в кталог программы
if (!Directory.Exists(currentfileName))
{
Directory.CreateDirectory(currentfileName);
}
FileStream downloadedFile = new FileStream(currentfileName + #"\" + path.Substring(path.LastIndexOf('/') + 1), FileMode.Create, FileAccess.ReadWrite);
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
//Получаем входящий поток
Stream responseStream = ftpResponse.GetResponseStream();
//Буфер для считываемых данных
byte[] buffer = new byte[1024];
int size = 0;
while ((size = responseStream.Read(buffer, 0, 1024)) > 0)
{
downloadedFile.Write(buffer, 0, size);
}
ftpResponse.Close();
downloadedFile.Close();
responseStream.Close();
}
//метод протокола FTP STOR для загрузки файла на FTP-сервер
public void UploadFile(string path, string fileName)
{
//для имени файла
string shortName = fileName.Remove(0, fileName.LastIndexOf("\\") + 1);
FileStream uploadedFile = new FileStream(fileName, FileMode.Open, FileAccess.Read);
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + shortName);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
//Буфер для загружаемых данных
byte[] file_to_bytes = new byte[uploadedFile.Length];
//Считываем данные в буфер
uploadedFile.Read(file_to_bytes, 0, file_to_bytes.Length);
uploadedFile.Close();
//Поток для загрузки файла
Stream writer = ftpRequest.GetRequestStream();
writer.Write(file_to_bytes, 0, file_to_bytes.Length);
writer.Close();
}
//метод протокола FTP DELE для удаления файла с FTP-сервера
public void DeleteFile(string path)
{
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
//метод протокола FTP MKD для создания каталога на FTP-сервере
public void CreateDirectory(string path, string folderName)
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + folderName);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
//метод протокола FTP RMD для удаления каталога с FTP-сервера
public void RemoveDirectory(string path)
{
string filename = path;
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
}
//Для парсинга полученного детального списка каталогов фтп-сервера
//Структура для хранения детальной информации о файле или каталоге
public struct FileStruct
{
public string Flags;
public string Owner;
public bool IsDirectory;
public string CreateTime;
public string Name;
}
public enum FileListStyle
{
UnixStyle,
WindowsStyle,
Unknown
}
//Класс для парсинга
public class DirectoryListParser
{
private List<FileStruct> _myListArray;
public FileStruct[] FullListing
{
get
{
return _myListArray.ToArray();
}
}
public FileStruct[] FileList
{
get
{
List<FileStruct> _fileList = new List<FileStruct>();
foreach (FileStruct thisstruct in _myListArray)
{
if (!thisstruct.IsDirectory)
{
_fileList.Add(thisstruct);
}
}
return _fileList.ToArray();
}
}
public FileStruct[] DirectoryList
{
get
{
List<FileStruct> _dirList = new List<FileStruct>();
foreach (FileStruct thisstruct in _myListArray)
{
if (thisstruct.IsDirectory)
{
_dirList.Add(thisstruct);
}
}
return _dirList.ToArray();
}
}
public DirectoryListParser(string responseString)
{
_myListArray = GetList(responseString);
}
private List<FileStruct> GetList(string datastring)
{
List<FileStruct> myListArray = new List<FileStruct>();
string[] dataRecords = datastring.Split('\n');
//Получаем стиль записей на сервере
FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
foreach (string s in dataRecords)
{
if (_directoryListStyle != FileListStyle.Unknown && s != "")
{
FileStruct f = new FileStruct();
f.Name = "..";
switch (_directoryListStyle)
{
case FileListStyle.UnixStyle:
f = ParseFileStructFromUnixStyleRecord(s);
break;
case FileListStyle.WindowsStyle:
f = ParseFileStructFromWindowsStyleRecord(s);
break;
}
if (f.Name != "" && f.Name != "." && f.Name != "..")
{
myListArray.Add(f);
}
}
}
return myListArray;
}
//Парсинг, если фтп сервера работает на Windows
private FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
{
//Предположим стиль записи 02-03-04 07:46PM <DIR> Append
FileStruct f = new FileStruct();
string processstr = Record.Trim();
//Получаем дату
string dateStr = processstr.Substring(0, 8);
processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
//Получаем время
string timeStr = processstr.Substring(0, 7);
processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
f.CreateTime = dateStr + " " + timeStr;
//Это папка или нет
if (processstr.Substring(0, 5) == "<DIR>")
{
f.IsDirectory = true;
processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
}
else
{
string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
processstr = strs[1];
f.IsDirectory = false;
}
//Остальное содержмое строки представляет имя каталога/файла
f.Name = processstr;
return f;
}
//Получаем на какой ОС работает фтп-сервер - от этого будет зависеть дальнейший парсинг
public FileListStyle GuessFileListStyle(string[] recordList)
{
foreach (string s in recordList)
{
//Если соблюдено условие, то используется стиль Unix
if (s.Length > 10
&& Regex.IsMatch(s.Substring(0, 10), "(-|d)((-|r)(-|w)(-|x)){3}"))
{
return FileListStyle.UnixStyle;
}
//Иначе стиль Windows
else if (s.Length > 8
&& Regex.IsMatch(s.Substring(0, 8), "[0-9]{2}-[0-9]{2}-[0-9]{2}"))
{
return FileListStyle.WindowsStyle;
}
}
return FileListStyle.Unknown;
}
//Если сервер работает на nix-ах
private FileStruct ParseFileStructFromUnixStyleRecord(string record)
{
//Предположим. тчо запись имеет формат dr-xr-xr-x 1 owner group 0 Nov 25 2002 bussys
FileStruct f = new FileStruct();
if (record[0] == '-' || record[0] == 'd')
{// правильная запись файла
string processstr = record.Trim();
f.Flags = processstr.Substring(0, 9);
f.IsDirectory = (f.Flags[0] == 'd');
processstr = (processstr.Substring(11)).Trim();
//отсекаем часть строки
_cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
f.CreateTime = getCreateTimeString(record);
//Индекс начала имени файла
int fileNameIndex = record.IndexOf(f.CreateTime) + f.CreateTime.Length;
//Само имя файла
f.Name = record.Substring(fileNameIndex).Trim();
}
else
{
f.Name = "";
}
return f;
}
private string getCreateTimeString(string record)
{
//Получаем время
string month = "(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)";
string space = #"(\040)+";
string day = "([0-9]|[1-3][0-9])";
string year = "[1-2][0-9]{3}";
string time = "[0-9]{1,2}:[0-9]{2}";
Regex dateTimeRegex = new Regex(month + space + day + space + "(" + year + "|" + time + ")", RegexOptions.IgnoreCase);
Match match = dateTimeRegex.Match(record);
return match.Value;
}
private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
{
int pos1 = s.IndexOf(c, startIndex);
string retString = s.Substring(0, pos1);
s = (s.Substring(pos1)).Trim();
return retString;
}
}
}
and this void
//Построение дерева файловой системы ftp сервера
private static void ListDirectory(TreeView treeView, string Host, string UserName, string password)
{
Ftp_Client ftp = new Ftp_Client();
ftp.Host = Host;
ftp.UserName = UserName;
ftp.Password = password;
treeView.Nodes.Clear();
var stack = new Stack<TreeNode>();
var rootDirectory = DOMAIN;
var node = new TreeNode(rootDirectory) { Tag = "/" };
stack.Push(node);
while (stack.Count > 0)
{
try
{
var currentNode = stack.Pop();
var directoryInfo = ftp.ListDirectory((string)currentNode.Tag);
foreach (var directory in directoryInfo)
{
if (directory.IsDirectory && directory.Name!="?") {
var childDirectoryNode = new TreeNode(directory.Name) { Tag = currentNode.Tag+directory.Name+'/'};
currentNode.Nodes.Add(childDirectoryNode);
stack.Push(childDirectoryNode);
}
}
foreach (var file in directoryInfo)
if (!file.IsDirectory && file.Name != "?")
currentNode.Nodes.Add(new TreeNode(file.Name) { Tag = currentNode.Tag + file.Name + "/f"}); ; //пометка f в конце пути означает, что это файл!
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
treeView.Nodes.Add(node);
}
calling by
ListDirectory(treeView1,DOMAIN,USER,PASS);