Hey!
Ich hab ein kleines Problem.
Ich möchte aus einem ausgelesenen Wert ein Byte Array machen.
Jedoch kann ich es vorher nicht in einen String umwandeln weil dann nur sinnloses Zeugs rauskommt.
Also muss ich es schaffen irgendwie den Wert direkt in ein Byte Array zu bauen.
Mein Code sieht wie folgt aus:
.....
byte[] bbyte = (byte[]) Zeile["name_value"];
Result += Rename(bbyte);
.......
Das war meine Idee es umzusetzen jedoch bekomme ich den folgenden Error:
Das Objekt des Typs "System.String" kann nicht in Typ "System.Byte[]" umgewandelt werden.
Da werde ich leider nicht schlau draus....
Hat jemand eine Idee wie man diesen Wert direkt in ein ByteArray umsetzen kann?
Wäre echt dankbar!
Liebe Grüße
Hey!
Danke für die Antwort aber das klappt leider nicht 😦
1-Argument: kann nicht von "object" in "bool" konvertiert werden.
Noch wer anders eine Idee?
Hallo Andybritten,
was versuchst du da überhaupt?
Das sieht mir irgendwie nach wilder umcasterei von Objekten aus.
Von wo nach wo soll es überhaupt gehen?
Zusätzlich würde ich dich gerne auf Punkt 5 der Regeln hinweisen. [Hinweis] Wie poste ich richtig?
Hallo,
Da werde ich leider nicht schlau draus....
Das geht mir mit Deiner ersten Frage ehrlich gesagt genauso:
Du sagst, Du kannst den Wert nicht in einen String umwandeln.
In dem von Dir geposteten Lösungsansatz wird der Wert ja aus Zeile["name_value"] gelesen.
Der ebenfalls geposteten Fehlermeldung zufolge handelt es sich dabei aber bereits um einen String,
Dein Ansatz - würde er funktionieren - käme also nach meinem Verständnis schon zu spät.
Du wirst schon mal erklären müssen, um was für einen ominösen Wert es sich da dreht.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Also.
Es handelt sich um eine SQLite Datenbankdatei die ich auselsen möchte.
Die SQLite Class sieht wie folgt aus: (Diese ist nicht von mir)
#region SQLite
public class SQLiteBase
{
// imports system functions for work with pointers
[DllImport("kernel32")]
private extern static IntPtr HeapAlloc(IntPtr heap, UInt32 flags, UInt32 bytes);
[DllImport("kernel32")]
private extern static IntPtr GetProcessHeap();
[DllImport("kernel32")]
private extern static int lstrlen(IntPtr str);
// imports SQLite functions
[DllImport("sqlite3")]
private static extern int sqlite3_open(IntPtr fileName, out IntPtr database);
[DllImport("sqlite3")]
private static extern int sqlite3_close(IntPtr database);
[DllImport("sqlite3")]
private static extern int sqlite3_exec(IntPtr database, IntPtr query, IntPtr callback, IntPtr arguments, out IntPtr error);
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_errmsg(IntPtr database);
[DllImport("sqlite3")]
private static extern int sqlite3_prepare_v2(IntPtr database, IntPtr query, int length, out IntPtr statement, out IntPtr tail);
[DllImport("sqlite3")]
private static extern int sqlite3_step(IntPtr statement);
[DllImport("sqlite3")]
private static extern int sqlite3_column_count(IntPtr statement);
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_column_name(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern int sqlite3_column_type(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern int sqlite3_column_int(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern double sqlite3_column_double(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_column_text(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_column_blob(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_column_table_name(IntPtr statement, int columnNumber);
[DllImport("sqlite3")]
private static extern int sqlite3_finalize(IntPtr handle);
// SQLite constants
private const int SQL_OK = 0;
private const int SQL_ROW = 100;
private const int SQL_DONE = 101;
/// <summary>
/// SQLite data types.
/// </summary>
public enum SQLiteDataTypes
{
/// <summary>
/// Integer numbers.
/// </summary>
INT = 1,
/// <summary>
/// Decimal numbers.
/// </summary>
FLOAT,
/// <summary>
/// All kinds of texts.
/// </summary>
TEXT,
/// <summary>
/// Blob objects - binary large objects.
/// </summary>
BLOB,
/// <summary>
/// Nothing.
/// </summary>
NULL
};
// pointer to database
private IntPtr database;
/// <summary>
/// Creates new instance of SQLiteBase class with no database attached.
/// </summary>
public SQLiteBase()
{
database = IntPtr.Zero;
}
/// <summary>
/// Creates new instance of SQLiteBase class and opens database with given name.
/// </summary>
/// <param name="baseName">Name (and path) to SQLite database file</param>
public SQLiteBase(String baseName)
{
OpenDatabase(baseName);
}
/// <summary>
/// Opens database.
/// </summary>
/// <param name="baseName">Name of database file</param>
public void OpenDatabase(String baseName)
{
// opens database
if (sqlite3_open(StringToPointer(baseName), out database) != SQL_OK)
{
// if there is some error, database pointer is set to 0 and exception is throws
database = IntPtr.Zero;
throw new Exception("Error with opening database " + baseName + "!");
}
}
/// <summary>
/// Closes opened database.
/// </summary>
public void CloseDatabase()
{
// closes the database if there is one opened
if (database != IntPtr.Zero)
{
sqlite3_close(database);
}
}
/// <summary>
/// Returns the list of tables in opened database.
/// </summary>
/// <returns></returns>
public ArrayList GetTables()
{
// executes query that select names of all tables and views in master table of every database
String query = "SELECT name FROM sqlite_master " +
"WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'" +
"UNION ALL " +
"SELECT name FROM sqlite_temp_master " +
"WHERE type IN ('table','view') " +
"ORDER BY 1";
DataTable table = ExecuteQuery(query);
// when table is generater, it writes all table names in list that is returned
ArrayList list = new ArrayList();
foreach (DataRow row in table.Rows)
{
list.Add(row.ItemArray[0].ToString());
}
return list;
}
/// <summary>
/// Executes query that does not return anything (e.g. UPDATE, INSERT, DELETE).
/// </summary>
/// <param name="query"></param>
public void ExecuteNonQuery(String query)
{
// calles SQLite function that executes non-query
IntPtr error;
sqlite3_exec(database, StringToPointer(query), IntPtr.Zero, IntPtr.Zero, out error);
// if there is error, excetion is thrown
if (error != IntPtr.Zero)
throw new Exception("Error with executing non-query: \"" + query + "\"!\n" + PointerToString(sqlite3_errmsg(error)));
}
/// <summary>
/// Executes query that does return something (e.g. SELECT).
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public DataTable ExecuteQuery(String query)
{
// processed query
IntPtr statement;
// excess data, it has no use
IntPtr excessData;
// process query and make statement
sqlite3_prepare_v2(database, StringToPointer(query), GetPointerLenght(StringToPointer(query)), out statement, out excessData);
// table for result of function
DataTable table = new DataTable();
// reads first row - it is different from next rows because it also creates table columns
// result - returns SLQ_ROW while there is next row
int result = ReadFirstRow(statement, ref table);
// reads rows
while (result == SQL_ROW)
{
result = ReadNextRow(statement, ref table);
}
// finalize executing this query
sqlite3_finalize(statement);
// returns table
return table;
}
// private function for reading firs row and creating DataTable
private int ReadFirstRow(IntPtr statement, ref DataTable table)
{
// create new instance of DataTable with name "resultTable"
table = new DataTable("resultTable");
// evaluates statement
int resultType = sqlite3_step(statement);
// if result of statement is SQL_ROW, create new table and write row in it
if (resultType == SQL_ROW)
{
// returns number of columns returned by statement
int columnCount = sqlite3_column_count(statement);
// declartaion of variables for reading first row
String columnName = "";
int columnType = 0;
object[] columnValues = new object[columnCount];
// reads columns one by one
for (int i = 0; i < columnCount; i++)
{
// returns the name of current column
columnName = PointerToString(sqlite3_column_name(statement, i));
// returns the type of current column
columnType = sqlite3_column_type(statement, i);
// checks type of columns - neccessary because different functions are required for different types
switch (columnType)
{
// in case of integer column
case (int)SQLiteDataTypes.INT:
{
// adds new integer column to table
table.Columns.Add(columnName, Type.GetType("System.Int32"));
// writes column value in object array
columnValues[i] = sqlite3_column_int(statement, i);
break;
}
// same as for integer, this one is for float
case (int)SQLiteDataTypes.FLOAT:
{
table.Columns.Add(columnName, Type.GetType("System.Single"));
columnValues[i] = sqlite3_column_double(statement, i);
break;
}
// ... for text
case (int)SQLiteDataTypes.TEXT:
{
table.Columns.Add(columnName, Type.GetType("System.String"));
columnValues[i] = PointerToString(sqlite3_column_text(statement, i));
break;
}
// ... for blob - blob are written in table as strings!!
case (int)SQLiteDataTypes.BLOB:
{
table.Columns.Add(columnName, Type.GetType("System.String"));
columnValues[i] = PointerToString(sqlite3_column_blob(statement, i));
break;
}
// in case of something other, value is read as string
default:
{
table.Columns.Add(columnName, Type.GetType("System.String"));
columnValues[i] = "";
break;
}
}
}
// writes column values to table
table.Rows.Add(columnValues);
}
// evalute statemnet for next results
return sqlite3_step(statement);
}
// private function for reading rows other than first
// it' same like first row, only without creating table and columns
private int ReadNextRow(IntPtr statement, ref DataTable table)
{
int columnCount = sqlite3_column_count(statement);
int columnType = 0;
object[] columnValues = new object[columnCount];
for (int i = 0; i < columnCount; i++)
{
columnType = sqlite3_column_type(statement, i);
switch (columnType)
{
case (int)SQLiteDataTypes.INT:
{
columnValues[i] = sqlite3_column_int(statement, i);
break;
}
case (int)SQLiteDataTypes.FLOAT:
{
columnValues[i] = sqlite3_column_double(statement, i);
break;
}
case (int)SQLiteDataTypes.TEXT:
{
columnValues[i] = PointerToString(sqlite3_column_text(statement, i));
break;
}
case (int)SQLiteDataTypes.BLOB:
{
columnValues[i] = PointerToString(sqlite3_column_blob(statement, i));
break;
}
default:
{
columnValues[i] = "";
break;
}
}
}
table.Rows.Add(columnValues);
return sqlite3_step(statement);
}
// converts string to pointer
private IntPtr StringToPointer(String str)
{
// if string is null, pointer is 0
if (str == null)
{
return IntPtr.Zero;
}
else
{
// else, convert it to pointer
Encoding encoding = Encoding.UTF8;
Byte[] bytes = encoding.GetBytes(str);
int length = bytes.Length + 1;
IntPtr pointer = HeapAlloc(GetProcessHeap(), 0, (UInt32)length);
Marshal.Copy(bytes, 0, pointer, bytes.Length);
Marshal.WriteByte(pointer, bytes.Length, 0);
return pointer;
}
}
// convert pointer to string
private String PointerToString(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return null;
Encoding encoding = Encoding.UTF8;
int length = GetPointerLenght(ptr);
Byte[] bytes = new Byte[length];
Marshal.Copy(ptr, bytes, 0, length);
return encoding.GetString(bytes, 0, length);
}
// returns length of pointer
private int GetPointerLenght(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return 0;
return lstrlen(ptr);
}
}
#endregion
Und mein Code sieht wie folgt aus:
SQLiteBase db = new SQLiteBase(Environment.GetFolderPath(PfadZurDatenbankDatei);
DataTable table = db.ExecuteQuery("SELECT * FROM database;");
foreach (DataRow Zeile in table.Rows)
{
string Result = Decrypt(Zeile["name_value"]);
Console.WriteLine(Result);
}
Die Decryption Routine benötigt ein Byte Array als input.
Und Zeile["name_value"] ist noch kein String man kann es aber mit: Zeile["name_value"].ToString() zu einem String machen.
Jedoch wenn ich diesen String dann in ein ByteArray umwandel stimmen die Werte nicht mehr.
Deswegen muss ich einen Weg finden den Ausgelesenen Wert DIREKT in ein byte Array umzuwandeln.
Ich hoffe meine Problembeschreibung war diesmal besser.
Hallo,
in der switch-case-Abfrage in den ReadLine-Methoden wird alles als String eingelesen, was nicht INT, FLOAT, TEXT, BLOB oder NULL ist. Ich vermute daher, daß Dein _Zeile["name_value"] _ entgegen Deiner Behauptung sehr wohl einen String enthält, und da wohl auch das Problem herrührt.
Ich empfehle diese Dokumentation der SQLite3-Datentypen
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
@Andybritten:
Bitte tu dir das nicht an.
Diese komische SQLite Klasse ist so grausselig und schlecht, das es nicht wirklich
sinnvoll ist.
Es gibt einen guten SQLite ADO.NET Provider der ganz Frameworkkonform
den Zugriff auf SQLite datenbanken erlaubt.
http://sqlite.phxsoftware.com/
Da musst du dann nichts irgendwie selber hin und her Konvertieren.
Hey!
Danke für deine Antwort aber das löst immer noch nicht mein Problem wie ich das "Object" zu einem "Byte Array" konvertiert bekomme...
Und wie bereits gesagt wurde... Wenn ich den Wert.ToString() mache bekomm ich einen Fehler beim decoden....
Grüße
FZelle:
Danke ich werd mir deine Klasse mal anschauen!
Aber erst morgen früh ^^
Allsssoooo nach ein bisschen rumprobieren habe ich es zum Laufen bekommen jedoch bleib ich bei dem selben Problem stecken wie zuvor!
Jedoch verstehe ich wieder etwas nicht....
Also mein Code sieht wie folgt aus:
using (DbConnection cnn = new SQLiteConnection("Data Source=" + datapath))
using (DbCommand cmd = cnn.CreateCommand())
{
cnn.Open();
cmd.CommandText = "SELECT * FROM database";
using (DbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string name = Decrypt(reader[5]);
Console.WriteLine(name);
}
}
}
Jetzt bekomme ich in der Zeile:
string name = Decrypt(reader[5]);
Den selben Error wie zuvor:
1-Argument: kann nicht von "object" in "byte[]" konvertiert werden.
Und nun zu dem was ich nicht verstehe.
Ich hab mir mal den Typ ausgeben lassen von dem "reader[5]" Wert.
string typeofthisshit = reader[5].GetType().ToString();
Und ratet mal was als Ergebnis rauskam....
System.Byte[]
Jetzt verstehe ich aber nicht warum er mir dann beim Aufruf der Decryption Methode anzeigt, dass er object nicht zu byte[] konvertieren kann wenns doch eh schon ein bytearray ist....
Und falls noch jemand Zweifel an der Decryption methode hat:
public static string Decrypt(byte[] Datas)
{
..............................
}
Ich steh grad total auf dem Schlauch! 😦
Hallo,
wenn es sich bei dem Wert schon um ein byte[] handelt, kannst Du ihn auch beim übergeben einfach casten.
string name = Decrypt((byte[])reader[5]);
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Es klappt!!!! Danke Leute.
Bei der alten methode hatte ich es mit (byte[]) probiert nur eben hab ich es vergessen...
Vielen Dank für die Hilfe! 😃