Προς το περιεχόμενο

C# & Random Access Files


Προτεινόμενες αναρτήσεις

Δημοσ.

Εχω βρει τον παρακατω κωδικα σε C# για αρχεια τυχαιας προσπελασης και θελω να μαθω αν μπορω να κανω το ιδιο χωρις να χρησιμοποιησω το namespace VisualBasic. Εχω δουλεψει με αρχεια τυχαιας προσπαλεασης σε VB.NET με τον ιδιο τροπο και με εχει βολεψει πολυ. Υπαρχει τροπος να γινει το ιδιο σε C#;

 

Ευχαριστω

 

 

>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharp_Syntax
{
class Program
{
 static void Main(string[] args)
 {
	 clsBinaryFileReadRandom myBinaryFileReadRandom = new clsBinaryFileReadRandom();
	 myBinaryFileReadRandom.Main();
 }
}
}

 

 

>using System;
using System.IO;
using Microsoft.VisualBasic;

// This example is from http://IdealProgrammer.com

public class clsBinaryFileReadRandom
{




public void Main()
{
Product prod = new Product();

//Find next available file number
int file_num = Microsoft.VisualBasic.FileSystem.FreeFile();

//Open file in random mode so we can write the records
Microsoft.VisualBasic.FileSystem.FileOpen(file_num, "Products.DAT", Microsoft.VisualBasic.OpenMode.Random, Microsoft.VisualBasic.OpenAccess.ReadWrite, Microsoft.VisualBasic.OpenShare.Shared, Microsoft.VisualBasic.Strings.Len(prod));

//Write the records
try
{
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(1, "My Little Red Reader", "Book"), -1);
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(2, "2001", "Video"), -1);
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(3, "Dell Laptop", "Computer"), -1);
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(4, "Toyota", "Car"), -1);
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(5, "Cat", "Pet"), -1);
Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(6, "Carrots", "Food"), -1);

}
catch (FileNotFoundException fileException)
{
Console.WriteLine("File Does Not Exits");
}
catch (FormatException formattingException)
{
Console.WriteLine("Invalid Format");


}


//Read the records
ValueType myProd = (ValueType)prod;
for (var i = 6; i >= 1; i -= 2)
{
Microsoft.VisualBasic.FileSystem.FileGet(file_num, ref myProd, i);
prod = (Product)myProd;
Console.WriteLine(prod.ToString());
}

// Close the file.
try
{
Microsoft.VisualBasic.FileSystem.FileClose(file_num);
}
catch (IOException e)
{
Console.WriteLine("Cannot close file");
}


//pause the console window
Console.ReadLine();
}
}

public struct Product
{
public int ID;
[VBFixedString(25)]
public string ProductName;
[VBFixedString(25)]
public string ProductType;

public Product(int new_id, string product_name, string product_type) : this()
{
ID = new_id;
ProductName = product_name;
ProductType = product_type;
}

public override string ToString()
{
return ID + ": " + ProductName + " " + ProductType;
}
}

Δημοσ.

Δεν ψαχνεις για Random μπλα μπλα αλλα για marshaling.

 

Ενα παραδειγμα

>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace ConsoleApplication3
{
   [structLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
   public struct PODStruct
   {
    public int Id;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string SomeString;
    public override string ToString()
    {
	    return string.Format("PODStruct ID:{0}\t SomeString:{1}",Id,SomeString);
    }
   }
   public class POD
   {
    public POD()
    {
	    Random r = new Random();
	    byte[] rawData = new byte[Marshal.SizeOf(typeof(PODStruct))];
	    GCHandle hMem = GCHandle.Alloc(rawData, GCHandleType.Pinned);
	    PODStruct ps = new PODStruct();
	    Console.WriteLine("Creating test.pod random File.\n");
	    using (FileStream fs = new FileStream("test.pod", FileMode.Append))
	    {
		    for (int i = 1; i < 10; i++)
		    {
			    ps.Id = i;
			    ps.SomeString = Guid.NewGuid().ToString();//random string
			   
			    Marshal.StructureToPtr(ps, hMem.AddrOfPinnedObject(),false);
			    Console.WriteLine("Writing..\n{0}\n",ps);
			    fs.Write(rawData, 0, rawData.Count());
		    }
	    }
	   
	   
	    Console.WriteLine("Reading 7th Record(PODStruct)\n");
	    using (FileStream fs = new FileStream("test.pod",FileMode.Open))
	    {
		  
		    fs.Seek(Marshal.SizeOf(typeof(PODStruct)) * 7, SeekOrigin.Begin);
		    fs.Read(rawData, 0, rawData.Count());
		    ps = (PODStruct)Marshal.PtrToStructure(hMem.AddrOfPinnedObject(), ps.GetType());
		    Console.WriteLine(ps);
		    Console.WriteLine("Setting someString to \"New String\"");
		    ps.SomeString = "New String";
		    Marshal.StructureToPtr(ps, hMem.AddrOfPinnedObject(), false);
		    fs.Write(rawData, 0, rawData.Count());
	    }
	    hMem.Free(); // <---- prosoxh!!!
    }
   }
}

Δημοσ.

hMem.Free(); // <---- prosoxh!!!

 

Αφου δεν χρειαστηκε να γραψω assembly ή κωδικα μηχανης για να το επιτυχω παλι καλα. Ο κωδικας στο #1 φαινεται πολυ πιο απλος και κατανοητος.

Δημοσ.

Αφου δεν χρειαστηκε να γραψω assembly ή κωδικα μηχανης για να το επιτυχω παλι καλα. Ο κωδικας στο #1 φαινεται πολυ πιο απλος και κατανοητος.

Κοιτα, αν δεν θες να χρησιμοποιησεις ολα τα αλλα εργαλεια που σου προσφερει το .net, και θες μονο pod τοτε μπορεις να χησιμοποισεις αλλες τεχνικες που σου προσφερει η c#. Πχ extensions

Βαζεις μεσα στο προγραμα σου ή σε καποιο dll

αυτο

>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace ConsoleApplication3
{
public static class ExtensionStreamForPod
{
 public static bool ReadPod<T>(this Stream stream, ref T podValueType) where T : struct
 {
	 var size = Marshal.SizeOf(podValueType);
	 byte[] rawData = new byte[size];
	 if (stream.Read(rawData, 0, size) != size)
		 return false;
	 GCHandle hMem = GCHandle.Alloc(rawData, GCHandleType.Pinned);
	 podValueType = (T)Marshal.PtrToStructure(hMem.AddrOfPinnedObject(), typeof(T));
	 hMem.Free();
	 return true;
 }
 public static void WritePod<T>(this Stream stream, ref T podValueType) where T : struct
 {
	 var size = Marshal.SizeOf(podValueType);
	 byte[] rawData = new byte[size];
	 GCHandle hMem = GCHandle.Alloc(rawData, GCHandleType.Pinned);
	 Marshal.StructureToPtr(podValueType, hMem.AddrOfPinnedObject(), false);
	 stream.Write(rawData, 0, size);
	 hMem.Free();
 }
}
}

 

Και μετα παιζεις μπαλα

 

>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleApplication3
{
[structLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SomePod
{
 public int Id;
 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
 public string SomeString;
 public override string ToString()
 {
	 return string.Format("PODStruct ID:{0}\t SomeString:{1}", Id, SomeString);
 }
}
class Program
{

 static void Main(string[] args)
 {
	 using (var stream = File.Open("test.bin", FileMode.Append))
	 {
		 SomePod sp = new SomePod { Id = 1, SomeString = "mpla mpla" };
		 stream.WritePod(ref sp);
		 sp.Id = 2;
		 sp.SomeString = "mpla mpla 2";
		 stream.WritePod(ref sp);
	 }
	 using (var stream = File.Open("test.bin", FileMode.Open))
	 {
		 SomePod sp = new SomePod();
		 while (stream.ReadPod(ref sp))
		 {
			 Console.WriteLine(sp);
		 }
	 }
	 Console.Read();
 }
}
}

Δημοσ.

παπι ο κωδικας σου δουλευει μια χαρα οπως ο #1.

 

Υπαρχει ομως το εξης προβλημα

 

Στον παρακατω κωδικα οπως φαινεται αλλαξα την τελευταια παραμετρο που ειναι ο αριθμος εγγραφης απο -1 σε 1

 

>		 Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(1, "My Little Red Reader", "Book"), 1);
	 Microsoft.VisualBasic.FileSystem.FilePut(file_num, new Product(1, "My Red Reader", "Book"), 1);

 

το αποτελεσμα ειναι να αλλαζει στην εγγραφη #1 το ProductName απο "My Little Red Reader" σε "My Red Reader".

 

Αυτο ακριβως θελω να πετυχω. Να μπορω π.χ. να πηγαινω σε μια εγγραφη και να αλλαζω τα περιεχομενα της ειτε απευθειας με τον αριθμο εγγραφης ειτε να σαρωνω το αρχειο απο την αρχη μεχρι το τελος ψαχνοτας την τιμη ενος πεδιου και εφοσον βρεθει να το αντικαθιστω. Αυτο εχω κανει στο παρελθον σε VB.NET με FileSystem.FilePut & FileSystem.FileGet κλπ.

 

Πως μπορει να γινει με τον τροπο που αναφερεις;

Ευχαριστω

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...