PDA

View Full Version : سوال: خواندن فقط قسمتی از بایت های یک فایل



s.a.s.a.n
دوشنبه 10 آذر 1393, 17:15 عصر
سلام به همه . میخواستم بدونم راهی هست که به جای خوندن همه ی بایت های فایل فقط قسمتی رو که میخوایم بخونیم ؟
مثلا یک فایل 100 بایتی داریم و من نمیخوام کل بایت های اون یا مثلا 20 بایت اول رو بخونم . من میخوام فایل رو مثلا به چهار قسمت تقسیم کنم و 25 بایت دوم رو بخونم . خیلی ممنون

mojtabamalaekeh
دوشنبه 10 آذر 1393, 19:02 عصر
سلام
آره میشه بدون Load کردن کل حجم فایل هم این کار رو کرد:

private void button1_Click(object sender, EventArgs e)
{
try
{
using (BinaryReader br = new BinaryReader(File.Open(@"Z:\Film\000.mpg", FileMode.Open)))
if (br.BaseStream.CanSeek)
{
br.BaseStream.Seek(1024 * 1024, SeekOrigin.Begin);
byte[] bytes = br.ReadBytes(50);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}


اینجا 1GB ازابتدای یه فایل خیلی حجیم رد شده بعد برا اینکه اذیتش کنیم فقط 50 بایتش رو خوندیم :لبخند:

اما در عمل باید روی فایلی تست بشه که میدونی هر بایتش چیه و میتونی چک کنی اون مقداری که با Seek خوندی درسته یا نه؟
بعد که به کد اعتماد کردی ازش استفاده کنی.

rasol_afkham
دوشنبه 10 آذر 1393, 19:04 عصر
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
br.ReadBytes(25);

path مسیر فایلی است که می خواهی اطلاعاتش را بخوانی.
اگر هم بخواهی از بایت 25ام و یا هر بایتی خواندن را شروع کنی کافیست مقدار خصوصیت fs.Position = 25 کنی. با اینکار اشارگر فایل به بایت 25ام می ره و خواندن را از آن بایت شروع می کنه.

s.a.s.a.n
دوشنبه 10 آذر 1393, 21:45 عصر
سلام
آره میشه بدون Load کردن کل حجم فایل هم این کار رو کرد:

private void button1_Click(object sender, EventArgs e)
{
try
{
using (BinaryReader br = new BinaryReader(File.Open(@"Z:\Film\000.mpg", FileMode.Open)))
if (br.BaseStream.CanSeek)
{
br.BaseStream.Seek(1024 * 1024, SeekOrigin.Begin);
byte[] bytes = br.ReadBytes(50);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}


اینجا 1GB ازابتدای یه فایل خیلی حجیم رد شده بعد برا اینکه اذیتش کنیم فقط 50 بایتش رو خوندیم :لبخند:

اما در عمل باید روی فایلی تست بشه که میدونی هر بایتش چیه و میتونی چک کنی اون مقداری که با Seek خوندی درسته یا نه؟
بعد که به کد اعتماد کردی ازش استفاده کنی.

خیلی ممنون . فقط این قسمت رو متوجه نشدم برا چیه ؟ :


br.BaseStream.Seek(1024 * 1024, SeekOrigin.Begin);

mojtabamalaekeh
دوشنبه 10 آذر 1393, 23:42 عصر
اصل کار همین Seek هست. خواستم یک گیگابایت از اول فایل برم جلو بعد شروع کنم به خوندن.
اون ضرب که انجام دادم برابر 1GB هست و پارامتر دوم هم میگه از کجا Seek کنم: Begin از ابتدا سیک میکنه، Current از محل فعلی کرسر سیک میکنه (مثلا اگه 10 بایت از BinaryReader گرفتی، از بایت دهم سیک میکنه)، End هم کرسر رو از آخر تنظیم میکنه که باید پارامتر اول رو منفی بدیم.

من فایل حجیم برداشتم که مطمئن شم کل فایل Load نمیشه و سرعت بالاست چون تا حالا با Seek کار نکرده بودم وگرنه برای خوندن 25 بایت دوم میشه:

br.BaseStream.Seek(25, SeekOrigin.Begin);
byte[] bytes = br.ReadBytes(25);

s.a.s.a.n
جمعه 14 آذر 1393, 18:06 عصر
اصل کار همین Seek هست. خواستم یک گیگابایت از اول فایل برم جلو بعد شروع کنم به خوندن.
اون ضرب که انجام دادم برابر 1GB هست و پارامتر دوم هم میگه از کجا Seek کنم: Begin از ابتدا سیک میکنه، Current از محل فعلی کرسر سیک میکنه (مثلا اگه 10 بایت از BinaryReader گرفتی، از بایت دهم سیک میکنه)، End هم کرسر رو از آخر تنظیم میکنه که باید پارامتر اول رو منفی بدیم.

من فایل حجیم برداشتم که مطمئن شم کل فایل Load نمیشه و سرعت بالاست چون تا حالا با Seek کار نکرده بودم وگرنه برای خوندن 25 بایت دوم میشه:

br.BaseStream.Seek(25, SeekOrigin.Begin);
byte[] bytes = br.ReadBytes(25);

خیلی ممنون :قلب: یاد گرفتم و دقیقا همونیه که میخواستم .
فقط یه سوال مبتدیانه : :خجالت: من میخوام به جا 25بایت 3 گیگ بخونم !! یعنی 3000000000 بایت ولی این عدد int نیست و به عنوان ورودی تابع قبول نمیشه . در چنین مواقعی چیکار میکنین شما ؟
واقعا ممنون میشم جواب بدین

mojtabamalaekeh
جمعه 14 آذر 1393, 19:17 عصر
در چنین مواقعی چیکار میکنین شما؟

در چنین مواقعی من کار خاصی نمیکنم چون سیستمم نمیکشه همچین فایلی رو Load کنم :لبخند:

این کد رو با یه فایل 50 بایتی تست کردم جواب داد. بجای int.MaxValue هم، 7 داده بودم:

private void button1_Click(object sender, EventArgs e)
{
string FileName = @"c:\test25.txt";
List<byte> bb = new List<byte>(0);
const int ValidMax = int.MaxValue;
long TotalBytesToRead = new FileInfo(FileName).Length;
try
{
using (BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open)))
while (TotalBytesToRead > 0)
{
int BytesToRead = ValidMax;
if (TotalBytesToRead >= ValidMax)
TotalBytesToRead -= ValidMax;
else
{
BytesToRead = (int)TotalBytesToRead;
TotalBytesToRead = 0;
}

byte[] bytes = br.ReadBytes(BytesToRead);
bb.AddRange(bytes);
};
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}



از متغیر BytesToRead هم میتونی استفاده نکنی و همون ValidMax رو به عنوان ورودی br.ReadBytes بدی. چرا؟ چون تابع ReadBytes اگه مقداری بیش از تعداد بایت های باقیمونده توی Stream بهش بدی هیچ خطایی نمیده و همون تعداد بایتی رو که باقی مونده، برمیگردونه.

rahnema1
جمعه 14 آذر 1393, 20:22 عصر
مطلب اشتباه بود