با سلام و عرض ادب خدمت کاربران عزیز با یکی دیگر از آموزش های برنامه نویسی جاوا تحت عنوان کار با فایل در جاوا در خدمت شما عزیزان هستیم. در این جلسه از آموزش قصد داریم دانلود فایل از اینترنت با استفاده از زبان جاوا را در یک مینی پروژه مورد بررسی قرار دهیم.
هدف اصلی این آموزش بررسی نحوه ی کار با فایل در جاوا ، دانلود از اینترنت با استفاده از زبان جاوا و کلاس های آن بوده که در قالب یک مینی پروژه آن را ارائه خواهیم داد.
حداقل پیش نیازهای لازم برای این آموزش آشنایی اولیه با مباحث OOP و Multithreading در جاوا است که می توانید از آموزش های همین سایت برای یادگیری آن ها استفاده کنید.
کلیه ی کدهای نوشته شده در این بخش در Netbeans 2.8 انجام شده و در محیط Eclipse نیز به راحتی قابل اجرا خواهد بود. در طول آموزش هر جا به کلاس جدیدی برخورد کردیم مختصری درباره آن توضیح خواهیم داد.
ابتدا یک پروژه ی جدید ایجاد کنید و نامی مناسب برای آن انتخاب نمایید.
سپس یک کلاس جاوا ایجاد کرده و قبل از انجام ادامه ی کار واسط Runnable را برای کلاس implements کنید و متد Run آن را Override و کدهای زیر را در داخل آن قدم به قدم بنویسید.
ابتدا لازم است متغیرهای لازم را در ابتدای برنامه تعریف کنید:
String link; File out; String filename; double filesize; double percentDownloaded=0.00;
لازم است دو متغیر link
و out
را در سازنده ی کلاس مقدار دهی کنیم که در ادامه با کاربرد این دو متغیر آشنا خواهیم شد.
Downloader(String link, File out) { this.link = link; this.out = out; }
من در اینجا نام Downloader
را برای کلاس در نظر گرفتم. تمامی کدهایی که در ادامه می نویسیم باید در متد Run نوشته شوند.
حال لازم است از کلاس URL
یک شی ایجاد کنیم:
URL url = new URL(link);
عبارت link
نوشته شده در سازنده ی کلاس در واقع حاوی لینک دانلود فایل مورد نظر ما خواهد بود. همان طور که می دانید عبارت URL مخفف Universal Resource Locator، در واقع حاوی یک صفحه در دنیای وب بوده که به وسیله آن می توان به صفحه مشخصی دست پیدا کرد، در جاوا نیز کلاسی با همین نام وجود دارد که دارای سازنده های مختلفی بوده که ساده ترین آن یک ورودی از نوع String می گیرد که ما نیز در این مثال از آن استفاده کرده ایم. از دیگر سازنده های این کلاس می توان به موارد زیر اشاره کرد:
public URL (java.lang.String protocol, java.lang.String host,java.lang.String file) public URL (java.lang.String protocol, java.lang.String host,int port, java.lang.String file) public URL (URL context, String spec)
تذکر: استفاده از کلاس URL باعث پرتاب خطا می شود بنابراین لازم است این خطای احتمالی با Try-Catch کنترل شود. درنتیجه کل کدهایی که در ادامه نوشته می شوند همگی در داخل بلوک Try قرار می گیرند.
بعد از آن لازم است یک کانکشن بین جاوا و آدرس صفحه ی مورد نظر ایجاد کنیم پس به صورت زیر عمل می کنیم:
URLConnection http = url.openConnection();
توجه داشته باشید که متد openConnection
در کلاس URL
وجود دارد و پارامتر بازگشتی آن از نوع URLConnection
است. URLConnection
یک کلاس انتزاعی بوده و امکان ساختن شئ مستقیم از آن وجود ندارد. خب در حال حاضر کانکشن ما به صفحه ی موردنظر (لینک فایل) باز شده و تمامی ویژگی های آن در شئ http
قرار گرفته است.
یکی از مهم ترین ویژگی های یک فایل، حجم آن است که در ادامه با استفاده از متدهایی که جاوا معرفی کرده به آن ها دست پیدا می کنیم.
حجم فایل را در یک متغیر سراسری از نوع double ذخیره می کنیم، این کار با استفاده از متد getContentLength
یا getContentLengthLong
به صورت زیر انجام خواهد گرفت:
filesize =(double) http.getContentLength()
این دو متد در کلاس انتزاعی URLConnection
قرار دارند همچنین دارای پارامتر ورودی نبوده، اما اولی پارامتر خروجی از نوع int و دومی از نوع Long دارد. زمان آن رسیده که نام فایل را از درون لینک دانلود بیرون بکشیم تا در جای مناسب از آن استفاده کنیم پس به این صورت عمل می کنیم:
filename = link.substring(link.lastIndexOf("/")+1);
متغیر filename
از نوع String بوده و تعریف اولیه ی آن به صورت سراسری در ابتدای برنامه انجام شده است. دلیل جمع کردن موقعیت آخرین "/"
با عدد 1 به منظور ایجاد یک substring بدون در نظر گرفتن کاراکتر "/"
است.
مهم ترین قسمت کار دریافت فایل و ذخیره ی آن بر روی هارد رایانه است. در این مورد ما با دو عمل مختلف روبرو هستیم، یکی از آن ها خواندن فایل از فضای اینترنت و دیگری نوشتن همان جریان داده ی خوانده شده بر روی هارد رایانه است که به صورت زیر عمل می کنیم:
BufferedInputStream bis= new BufferedInputStream(http.getInputStream()) BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(out), 1024)
وظیفه ی کلاس BufferedInputStream
خواندن جریان ورودی اطلاعات فایل است. ورودی سازنده ی این کلاس از نوع InputStream
است به همین منظور با استفاده از متد getInputStream
جریان داده را از شئ http
دریافت می کنیم.
در مرحله ی بعد لازم است با استفاده از BufferedOutputStream
مکان ذخیره ی فایل را بر روی هارد مشخص کنیم سازنده ی این کلاس یک شئ از نوع FileOutputStream
می گیرد که یک شی از نوع File
بوده و حاوی آدرس محل ذخیره ی فایل است ( شئ out
از نوع File
است).
به سه متغیر تعریف شده زیر توجه کنید:
byte[] buffer = new byte[1024]; double dowenloaded = 0.00; int count=0;
لازم است اطلاعات خوانده شده توسط شئ bis
به طور موقت در یک بافر با سایز مشخص نوشته شود، به همین دلیل آرایه ای از byte
با طول 1024 تعریف کرده ایم تا اطلاعات مرحله به مرحله از bis
خوانده و بر روی buffer
نوشته شوند. متغیر dowenloaded
و count
در ادامه ی بحث بررسی خواهد شد.
خب به مرحله ی بسیار مهم خواندن و نوشتن فایل رسیدیم با دقت بسیار زیاد به کدهای نوشته شده در زیر و توضیحات آن توجه کنید:
while((count=bis.read(buffer,0,1024))!=-1){ bos.write(buffer,0,count); dowenloaded+=count; percentDownloaded = (dowenloaded*100)/filesize; String percent = String.format("%3.2f",percentDownloaded); System.out.println("Downloaded "+ percent + "% of file "+ filename); } bis.close(); bos.close(); System.out.println("Download Complate "+out.getAbsolutePath()); System.exit(0);
با استفاده از یک while
و متد read
بایت به بایت اطلاعات را خوانده و درون buffer
ذخیره می کنیم، پارامتر اول را متد read
مشخص می کند که اطلاعات در کجا ذخیره شوند، پارامتر دوم شروع از یک نقطه ی مشخص را برای خواندن اطلاعات اعلام می کند و پارامتر سوم نیز طول اطلاعات را تعیین می نماید.
از آنجایی که طول buffer
را 1024 در نظر گرفتیم پس پارامتر سوم هم متناسب با آن انتخاب می کنیم. خروجی متد read
از نوع int
است و تا زمانی که مقدار آن منفی نشده حلقه به کار خود ادامه خواهد داد. در هر مرحله اجرای حلقه بلافاصله با استفاده از متد write
اطلاعات بر روی مکان ذخیره ی فایل نوشته می شوند.
پارامتر اول متد write
اطلاعاتی است که باید نوشته شوند و پارامتر دوم نقطه شروع نوشتن اطلاعات را مشخص می کند و پارامتر سوم که در اینجا count
در هر مرحله اجرای حلقه تا 1024 شمارش می کند و در خط بعدی مقدار آن به متغیر dowenloaded
اضافه می شود تا مقدار دانلود شده ی فایل در هر لحظه مشخص شود. در سه خط بعدی هم طی محاسبات ساده، درصد پیشرفت دانلود را محاسبه و نمایش داده ایم در آخر هم دو شئ bis
و bos
را close کردیم.
شکل کلی کلاسی که کدهای آن را قدم به قدم تکمیل کردیم به این صورت است:
public class Downloader implements Runnable{ String link; File out; String filename; double filesize; int pos=0; double percentDownloaded=0.00; Downloader(String link, File out) { this.link = link; this.out = out; } @Override public void run() { try { URL url = new URL(link); URLConnection http = url.openConnection(); filesize =(double) http.getContentLengthLong(); filename = link.substring(link.lastIndexOf("/")+1); BufferedInputStream in = new BufferedInputStream(http.getInputStream()); BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(out)); byte[] file = new byte[1024]; double dowenloaded = 0.00; int count=0; while((count=in.read(file,0,1024))!=-1){ bout.write(file,0,count); dowenloaded+=count; percentDownloaded = (dowenloaded*100)/filesize; String percent = String.format("%3.2f",percentDownloaded); System.out.println("Downloaded "+ percent + "% of file "+ filename); } in.close(); bout.close(); System.out.println("Download Complate "+out.getAbsolutePath()); System.exit(0); } catch (IOException e) { System.err.println(e.getMessage()); } } }
خب حالا لازم است کلاس Main را به این صورت تکمیل کنیم:
public static void main(String[] args) { String link="http://at1.cdn.asandl.com/software/network-internet/download-manager/IDM/Internet.Download.Manager.v6.32.Build.11_AsanDl.com.zip"; String filename = link.substring(link.lastIndexOf("/")+1); File out = new File("D:\\"+filename); Downloader downloader = new Downloader(link,out); new Thread(downloader).start(); } }
همان طور که مشاهده می کنید لینک دانلود یک فایل را برای مقداردهی به پارامتر اول سازنده ی کلاس ارسال کرده ایم و در قدم بعدی نام فایل را از داخل لینک جدا کرده تا فایل ذخیره شده همنام فایل اصلی باشد. در خط بعدی با استفاده از کلاس File
محل ذخیره سازی را مشخص کردیم و در آخر هم با ساختن شئ از کلاس و مقداردهی به سازنده ی آن Thread آن را Start کردیم تا با اجرای برنامه دانلود فایل آغاز شود. برنامه را اجرا کنید و پروسه ی دانلود فایل را مشاهده کنید.
امیدوارم درس کار با فایل در جاوا برای شما عزیزان مفید بوده باشد. موفق و سربلند باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.