একটি struct মধ্যে বাইনারি ফাইল পড়ুন

আমি সি # ব্যবহার করে বাইনারি তথ্য পড়ার চেষ্টা করছি। আমার কাছে যে ফাইলগুলি আমি পড়তে চাই তার মধ্যে ডেটা লেআউট সম্পর্কে সব তথ্য আছে। আমি ডাটা "চুক দ্বারা চুক" পড়তে সক্ষম, যেমন প্রথম 40 বাইটের ডাটা স্ট্রিংকে রূপান্তর করে, পরের 40 বাইট পান।

যেহেতু তথ্য কমপক্ষে তিনটি সামান্য ভিন্ন সংস্করণ রয়েছে, তাই আমি ডাটা সরাসরি একটি struct এ পড়তে চাই। এটা শুধু "লাইন দ্বারা লাইন" এটি পড়ার চেয়ে অনেক বেশি অধিকার অনুভব করে।

আমি নিম্নলিখিত পদ্ধতির চেষ্টা করেছি কিন্তু কোন উপকারে নেই:

StructType aStruct;
int count = Marshal.SizeOf(typeof(StructType));
byte[] readBuffer = new byte[count];
BinaryReader reader = new BinaryReader(stream);
readBuffer = reader.ReadBytes(count);
GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
aStruct = (StructType) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(StructType));
handle.Free();

স্ট্রিম একটি খোলা ফাইল স্ট্রীম যা থেকে আমি পড়তে শুরু করেছি Marshal.PtrToStructure ব্যবহার করার সময় আমি একটি অ্যাক্সেস ভিলেশন এক্সিকিউশন n পেতে পারি।

আমি ফাইলের শেষে ডেটাতে আগ্রহী নই যেহেতু স্ট্রিমটিতে আমি পড়ার চেষ্টা করছি সে সম্পর্কে আরো তথ্য রয়েছে।

কাঠামোটি সংজ্ঞায়িত করা হয়েছে:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    public string FileDate;
    [FieldOffset(8)]
    public string FileTime;
    [FieldOffset(16)]
    public int Id1;
    [FieldOffset(20)]
    public string Id2;
}

এই প্রশ্নটি ছোট করার জন্য উদাহরণ কোড মূল থেকে পরিবর্তিত হয়।

কিভাবে আমি একটি ফাইল থেকে বাইনারি তথ্য একটি struct পড়া হবে?

0

6 উত্তর

আমি BinaryFormatter ব্যবহার করে কোন ভাগ্য ছিল না, আমি অনুমান করছি আমার পুরো স্ট্রাক্ট আছে যে ফাইলের বিষয়বস্তু ঠিক ঠিক মেলে। আমি উপলব্ধি করি যে শেষ পর্যন্ত আমি কোনও ফাইলের বিষয়বস্তুতে খুব বেশি আগ্রহী ছিলাম না তাই আমি বাইটবফারের স্ট্রিমের অংশ পড়ার সমাধান নিয়ে গিয়ে তারপর এটি ব্যবহার করে রূপান্তর করেছিলাম।

Encoding.ASCII.GetString()

স্ট্রিং জন্য এবং

BitConverter.ToInt32()

পূর্ণসংখ্যা জন্য

আমি পরে আরো ফাইল পার্স করতে সক্ষম হতে হবে কিন্তু এই সংস্করণ জন্য আমি শুধু কয়েক লাইন কোড সঙ্গে দূরে চলে গেছে।

0
যোগ

স্ট্রাক্টগুলিতে সরাসরি পড়া পড়া খারাপ - অনেক বাইট অর্ডারিং, ক্ষেত্রের বিভিন্ন কম্পাইলার প্রয়োগ, প্যাকিং, শব্দ আকারের কারণে অনেক সি প্রোগ্রাম বন্ধ হয়ে গেছে .......

আপনি বাইট দ্বারা serialising এবং deserialising বাইট শ্রেষ্ঠ হয়। আপনি যদি চান বা শুধুমাত্র BinaryReader ব্যবহার করা হলে জিনিসপত্র মধ্যে বিল্ড ব্যবহার করুন।

0
যোগ
আমিও অসঙ্গত। যখন কার্যকারিতা কী, বা যখন আপনি বাইনারি C ++ / C# interop প্রয়োজন, তখন লিখিত সামগ্রীর কোড s লিখুন।
যোগ লেখক Dmitri Nesteruk, উৎস
আমি অসম্মতি, স্ট্রাক্ট মধ্যে সরাসরি পড়া কখনও কখনও একটি তথ্যযোগ্য বস্তুর মধ্যে আপনার তথ্য পেতে দ্রুততম উপায়। আপনি কর্মক্ষমতা ভিত্তিক কোড লেখার করছি যদি এটি খুব দরকারী হতে পারে। হ্যাঁ আপনি সারিবদ্ধতা এবং প্যাকিং সম্পর্কে সচেতন হতে হবে এবং নিশ্চিত করুন যে কোনও শেষ পয়েন্ট মেশিন একই ব্যবহার করবে।
যোগ লেখক Joe, উৎস

এটা চেষ্টা কর:

using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
    BinaryFormatter formatter = new BinaryFormatter();
    StructType aStruct = (StructType)formatter.Deserialize(filestream);
}
0
যোগ
বাইনারি ফরম্যাটের বাইনারি ডেটার জন্য তার নিজস্ব ফর্ম্যাট রয়েছে - যা আপনার নিজের ডেটা পড়া / লেখার সময় ভাল। আপনি যদি অন্য কোনও উৎস থেকে একটি ফাইল পেয়ে থাকেন তবে এটি দরকারী নয়।
যোগ লেখক russau, উৎস

সমস্যা আপনার struct মধ্যে স্ট্রিং s হয় আমি যে marshaling ধরনের বাইট / সংক্ষিপ্ত / int একটি সমস্যা হয় পাওয়া যায় নি; কিন্তু যখন আপনি একটি স্ট্রিং একটি জটিল টাইপ মধ্যে মার্শাল প্রয়োজন, আপনি স্পষ্টভাবে একটি unmanaged টাইপ অনুকরণ করা আপনার struct প্রয়োজন। আপনি MarshalAs attrib দিয়ে এটি করতে পারেন।

আপনার উদাহরণের জন্য নিম্নলিখিত কাজ করা উচিত:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileDate;

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileTime;

    [FieldOffset(16)]
    public int Id1;

    [FieldOffset(20)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 66)] //Or however long Id2 is.
    public string Id2;
}
0
যোগ

আমি আপনার কোড সঙ্গে কোন সমস্যা দেখতে না।

শুধু আমার মাথার বাইরে, আপনি কি নিজে নিজে চেষ্টা করবেন? এটা কি কাজ করে?

BinaryReader reader = new BinaryReader(stream);
StructType o = new StructType();
o.FileDate = Encoding.ASCII.GetString(reader.ReadBytes(8));
o.FileTime = Encoding.ASCII.GetString(reader.ReadBytes(8));
...
...
...

এছাড়াও চেষ্টা করুন

StructType o = new StructType();
byte[] buffer = new byte[Marshal.SizeOf(typeof(StructType))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();

তাহলে আপনি এখনও অ্যাক্সেস ভিলেশন ব্যতিক্রম পান কিনা তা দেখার জন্য FileStream থেকে ডেটা পড়ার পরিবর্তে বাফার [] ব্যবহার করুন।

আমার কোন ভাগ্য নাই   BinaryFormatter, আমি অনুমান আমার আছে   একটি সম্পূর্ণ স্ট্রাক্ট যে মিল আছে   ফাইলের বিষয়বস্তু ঠিক।

এটা বোঝা যায়, BinaryFormatter এর নিজস্ব ডেটা ফর্ম্যাট আছে, আপনার সাথে সম্পূর্ণরূপে অসামঞ্জস্যপূর্ণ।

0
যোগ

রনি বলেছেন, আমি বাইনারি রিডার ব্যবহার করব এবং প্রতিটি ক্ষেত্রকে পৃথকভাবে পড়ব। আমি এই তথ্য সহ নিবন্ধের লিঙ্কটি খুঁজে পাচ্ছি না, তবে এটি লক্ষ্য করা গেছে যে প্রত্যেকটি ক্ষেত্রটি পড়ার জন্য বাইনারি রেডার ব্যবহার করা মার্শাল। পিট্রো স্ট্রাস্টের চেয়ে দ্রুততর হতে পারে, যদি স্ট্রাক্ট 30-40 এর কম অথবা ক্ষেত্রগুলি থেকে কম থাকে আমি এটি খুঁজে যখন আমি নিবন্ধে লিঙ্ক পোস্ট করব।

The article's link is at: http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C

যখন structs একটি অ্যারের মার্শালিং, PtrToStruct আরও দ্রুত ঊর্ধ্ব হাত লাভ, কারণ আপনি ক্ষেত্রের গণনা * অ্যারের দৈর্ঘ্য হিসাবে মনে করতে পারেন।

0
যোগ
অবশ্যই এটা! ভাল সন্ধান :)
যোগ লেখক nevelis, উৎস
আমি শুধু পড়তে ছিলাম: codeproject.com/KB/files/fastbinaryfileinput.aspx । এই নিবন্ধটি আপনি চিন্তা করছেন? লেখক লিখেছেন: "আমি দেখেছি যে, প্রায় 40 টি ক্ষেত্রের মধ্যে, তিনটি পদ্ধতির ফলাফল প্রায় সমতুল্য, এবং এর বাইরে, ব্লক পড়ার পন্থাগুলি একটি উচ্চতর হাত লাভ করেছে।"
যোগ লেখক Neal Stublen, উৎস