VO17PHD – spoj

Đề bài

Thuật toán

  • (đang cập nhập)

Code

#include 
using namespace std;
#define FORE(i,a,b) for(int i = a; i <= b; ++i)
#define FORD(i,a,b) for(int i = a; i >= b; --i)
#define FOR(i,a,b) for(int i = a; i < b; ++i)
#define pb push_back
#define endl '\n'
#define ll long long
#define X first
#define Y second

const int MAXN = 1e5 * 5;
const int base = 1e9 + 7;
const int N = 5000;
typedef pair ii;
typedef pair iii;

int n,m;
int p[MAXN];
ll d[MAXN],f[MAXN];
priority_queue h;
vector a[MAXN],c[MAXN];

void dijkstra()
{
    FORE(i,1,n) d[i] = 1e15;
    FORE(i,1,n) f[i] = 0;
    d[1] = 0;
    f[1] = p[1];
    h.push(iii(ii(0,p[1]),1));
    while(h.size())
    {
        int u = h.top().Y;
        ll du = -h.top().X.X;
        ll fu = h.top().X.Y;
        h.pop();
        if (du != d[u] || f[u] != fu) continue;
        for(int i = 0; int v = a[u][i]; ++i)
        if (d[v] > d[u] + c[u][i])
        {
            d[v] = d[u] + c[u][i];
            f[v] = f[u] + p[v];
            h.push(iii(ii(-d[v],f[v]),v));
        }
        else
        if (d[v] == d[u] + c[u][i] && f[v] < f[u] + p[v])
        {
            f[v] = f[u] + p[v];
            h.push(iii(ii(-d[v],f[v]),v));
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("vo17phd.inp" , "r" , stdin);
    //("vo17phd.out" , "w" , stdout);
    cin>>n;
    FORE(i,1,n) cin>>p[i];
    cin>>m;
    FORE(i,1,m)
    {
        int u,v,w;
        cin>>u>>v>>w;
        a[u].pb(v); c[u].pb(w);
        a[v].pb(u); c[v].pb(w);
    }
    FORE(i,1,n) a[i].pb(0);
    dijkstra();
    if (d[n] == 1e15) cout<<"impossible"<

VO17LAN – spoj

Đề bài

Thuật toán

  • (đang cập nhập)

Code

#include 
using namespace std;
#define FORE(i,a,b) for(int i = a; i <= b; ++i)
#define FORD(i,a,b) for(int i = a; i >= b; --i)
#define FOR(i,a,b) for(int i = a; i < b; ++i)
#define pb push_back
#define endl '\n'
#define ll long long
#define X first
#define Y second

const int MAXN = 1e5 * 5;
const int base = 1e9 + 7;
const int N = 55000;

int t,n;
int ans;
int a[N];

int gcd(int a,int b)
{
    if (b == 0) return a;
    else return gcd(b,a%b);
}

void upd(int d)
{
    if (d <= ans) return;
    int gcd1 = a[1];
    int gcd2 = 0;
    FORE(i,2,n)
    {
        if (a[i]%d == 0) gcd1 = gcd(gcd1 , a[i]);
        else
        {
            if (gcd2 == 0) gcd2 = a[i];
            else gcd2 = gcd(gcd2 , a[i]);
        }
        if (gcd2 && min(gcd1 , gcd2) <= ans) return;
    }
    if (gcd2 == 0) gcd2 = gcd1;
    ans = max(ans , min(gcd1 , gcd2));
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("vo17lan.inp" , "r" , stdin);
    //freopen("vo17lan.out" , "w" , stdout);
    cin>>t;
    while(t--)
    {
        cin>>n;
        FORE(i,1,n) cin>>a[i];
        sort(a+1,a+n+1);
        ans = 1;
        int xx = sqrt(a[1]);
        FORD(d,xx,2)
        if (a[1]%d == 0)
        {
            upd(d);
            upd(a[1]/d);
        }
        upd(a[1]);
        cout<

Các kiểu dữ liệu trong Pascal

Kiểu số nguyên

Các kiểu số nguyên

Tên kiểu Phạm vi Dung lượng
Shortint -128 đến 127 1 byte
Byte 0 đến 255 1 byte
Integer -32768 đến 32767 2 byte
Word 0 đến 65535 2 byte
LongInt -2147483648 đến 2147483647 4 byte

int64          -2^63…2^63-1
qword         0…2^64-1

Các phép toán trên kiểu số nguyên

Các phép toán số học:

+, -, *, / (phép chia cho ra kết quả là số thực).

Phép chia lấy phần nguyên: DIV  (Ví dụ : 34 DIV 5 = 6).

Phép chia lấy số dư: MOD (Ví dụ:  34 MOD 5 = 4).

Các phép toán xử lý bit:

Trên các kiểu ShortInt, Integer, Byte, Word có các phép toán:

  • NOT, AND, OR, XOR.
A B A AND B A OR B A XOR B NOT A
1 1 1 1 0 0
1 0 0 1 1 0
0 1 0 1 1 1
0 0 0 0 0 1
  • SHL (phép dịch trái): a SHL n Û a ´ 2n
  • SHR (phép dịch phải): a SHR n Û a DIV 2n

Kiểu logic

– Từ khóa: BOOLEAN

– miền giá trị: (TRUE, FALSE).

– Các phép toán: phép so sánh (=, <, >) và các phép toán logic: AND, OR, XOR, NOT.

Trong Pascal, khi so sánh các giá trị boolean ta tuân theo qui tắc: FALSE < TRUE.

Giả sử A và B là hai giá trị kiểu Boolean. Kết quả của các phép toán được thể hiện qua bảng dưới đây:

A B A AND B A OR B A XOR B NOT A
TRUE TRUE TRUE TRUE FALSE FALSE
TRUE FALSE FALSE TRUE TRUE FALSE
FALSE TRUE FALSE TRUE TRUE TRUE
FALSE FALSE FALSE FALSE FALSE TRUE

Kiểu số thực

Các kiểu số thực:

Tên kiểu Phạm vi Dung lượng
Single 1.5´10-45 ® 3.4´10+38 4 byte
Real 2.9´10-39 ® 1.7´10+38 6 byte
Double 5.0´10-324 ® 1.7´10+308 8 byte
Extended 3.4´10-4932 ® 1.1´10+4932 10 byte

Chú ý: Các kiểu số thực Single, Double và Extended yêu cầu phải sử dụng chung với bộ đồng xử lý số hoặc phải biên dich chương trình với chỉ thị {$N+} để liên kết bộ giả lập số.

Các phép toán trên kiểu số thực:          

+, -, *, /

Chú ý: Trên kiểu số thực không tồn tại các phép toán DIV và MOD.

Các hàm số học sử dụng cho kiểu số nguyên và số thực:

SQR(x):                                  Trả về x2

SQRT(x):                                Trả về căn bậc hai của x (x³0)

ABS(x):                                   Trả về |x|

SIN(x):                                                Trả về sin(x) theo radian

COS(x):                                  Trả về cos(x) theo radian

ARCTAN(x): Trả về arctang(x) theo radian

LN(x):                                     Trả về ln(x)

EXP(x):                                  Trả về ex

TRUNC(x):                Trả về số nguyên gần với x nhất nhưng bé hơn x.

INT(x):                                               Trả về phần nguyên của x

FRAC(x):                               Trả về phần thập phân của x

ROUND(x):                Làm tròn số nguyên x

PRED(n):                               Trả về giá trị đứng trước n

SUCC(n):                               Trả về giá trị đứng sau n

ODD(n):                                 Cho giá trị TRUE nếu n là số lẻ.

INC(n):                                   Tăng n thêm 1 đơn vị (n:=n+1).

DEC(n):                                  Giảm n đi 1 đơn vị (n:=n-1).

Kiểu ký tự

– Từ khoá: CHAR.

– Kích thước: 1 byte.

– Để biểu diễn một ký tự, ta có thể sử dụng một trong số các cách sau đây:

  • Đặt ký tự trong cặp dấu nháy đơn. Ví dụ ‘A’, ‘0’.
  • Dùng hàm CHR(n) (trong đó n là mã ASCII của ký tự cần biểu diễn). Ví dụ CHR(65) biễu diễn ký tự ‘A’.
  • Dùng ký hiệu #n (trong đó n là mã ASCII của ký tự cần biểu diễn). Ví dụ #65.

– Các phép toán: =, >, >=, <, <=,<>.

* Các hàm trên kiểu ký tự:

UPCASE(ch): Trả về ký tự in hoa tương ứng với ký tự ch. Ví dụ: UPCASE(‘a’) = ‘A’.

ORD(ch): Trả về số thứ tự trong bảng mã ASCII của ký tự ch. Ví dụ ORD(‘A’)=65.

CHR(n): Trả về ký tự tương ứng trong bảng mã ASCII có số thứ tự là n. Ví dụ: CHR(65)=’A’.

PRED(ch): cho ký tự đứng trước ký tự ch. Ví dụ: PRED(‘B’)=’A’.

SUCC(ch): cho ký tự đứng sau ký tự ch. Ví dụ: SUCC(‘A’)=’B’.

Tài liệu chuyên đề thuật toán duyệt

Tải về: CHUYEN-DE-DUYET-CAU-HINH-TO-HOP-YEULAPTRINH.PW

Hiện nay chưa có tài liệu chính thức dành cho lớp Chuyên Tin khối THPT. Mà chỉ tồn tại ở dưới dạng tên chuyên đề của Bộ Giáo dục gửi về cho các trường. Do vậy việc dạy và học gặp nhiều khó khăn trong việc thống nhất về nội dung cũng như mức độ về kiến thức chuyên môn. Nên việc nghiên cứu và xây dựng chuyên đề này là thực sự cần thiết.

Mục đích của chuyên đề là truyền tải một cách tổng quát, chi tiết và sự thống nhất về mặt nội dung để người đọc dễ hiểu và thấy được tầm quan trọng của bài toán liệt kê tổ hợp và một số bài tập ứng dụng trong Tin học dành cho học sinh chuyên tin ở trường THPT.

Nội dung của chuyên đề đã được các tác giả chọn lọc qua chương trình đã thực dạy tại trường và tham khảo của một số đồng nghiệp khác trong nước.

Kiến thức là vô hạn, trong chuyên đề này chúng tôi đã có gắng sáng  tạo, sưu tầm và trao đổi một cách tốt nhất có thể về mặt lý thuyết, các bài tập ứng dụng và các bài tập trong các kỳ thi trong nước để tạo thành cuốn tài liệu hiệu quả dành cho giáo viên và các em học sinh đam mê tin học chính thức làm tài liệu cho mình trong quá trình học tập và nghiên cứu.

THPT Chuyên Bắc Giang.

 

Các hàm toán học có sẵn trong C++

YeuLapTrinh xin được tóm tắt một số các  hàm toán học hay dùng. Các hàm này đều được khai báo trong file nguyên mẫu math.h.

  1. Các hàm số học
  • abs(x), labs(x), fabs(x) : trả lại giá trị tuyệt đối của một số nguyên, số nguyên dài và số thực.
  • pow(x, y) : hàm mũ, trả lại giá trị x lũy thừa y (xy).
  • exp(x) : hàm mũ, trả lại giá trị e mũ x (ex).
  • log(x), log10(x) : trả lại lôgarit cơ số e và lôgarit thập phân của x (lnx, logx) .
  • sqrt(x) : trả lại căn bậc 2 của
  • atof(s_number) : trả lại số thực ứng với số viết dưới dạng xâu kí tự
  1. Các hàm lượng giác
  • sin(x), cos(x), tan(x) : trả lại các giá trị sinx, cosx,

Các phần mềm lập trình .NET, VB.NET, C#, ASP.NET

Công cụ để lập trình .NET (VB.NET, C#, ASP.NET) gồm có:

1. Visual Studio 2008 Professional Edition

2. Microsoft Visual Studio 2010 Ultimate v10.0.30319.1 Final Full Crack Actived

Bạn hãy chỉ chọn một trong hai công cụ trên.

1. Visual Studio 2008 Professional Edition
Dung lượng: 3.30 GB

http://download.microsoft.com/download/8/1/d/81d3f35e-fa03-485b-953b-ff952e402520/VS2008ProEdition90dayTrialENUX1435622.iso

Sau khi cài đặt xong, vào Start –> Control Panel –> Settings –> Add or Remove Programs
Chọn Visual Studio 2008 Professional Edition – ENU click chọn Change/Remove
Chờ 1 chút cho nó load lên, click Next
Nếu bản của bạn đang là bản dùng thử, nhìn xuống dưới cùng của cửa sổ Microsoft VS 2008 Setup Maintenance sẽ có chỗ Upgrade key.
Bạn điền key sau vào và click vào Upgrade là xong
Khi Crack xong, vào chương trình VS 2008 Pro Edition, click Help –> About nó sẽ hiện ra cửa sổ như sau và mất đi dòng Trial

Key: XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT

– Hướng dẫn Crack trên Windows 7:
Trên Windows 7, thì cách trên không hoạt động đc. Bạn hãy làm như sau:
+ Dùng Ultra ISO để mở file VS 2008, tìm tới file setup.sdb (nằm trong thư mục Setup).
+ Mở file setup.sdb bằng Notepad hoặc bất kỳ Editor nào.
+ Tìm tới dòng [Product Key] và sửa giá trị cho nó : XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT
Sau khi sửa xong, hãy lưu file setup.sdb lại và tiến hành cài đặt bình thường. Sau khi cài đặt xong, nó sẽ tự động Active cho bạn.

2. Microsoft Visual Studio 2010 Ultimate v10.0.30319.1 Final Full Crack Actived x86:

http://www.fshare.vn/folder/TX9VZR3V3T

Hoặc: Visual Studio 2010 Ultimate x86
http://up.4share.vn/f/66575f54545e5756/en_visual_studio_2010_ultimate_x86_dvd_509116.iso.file

3. Hệ quản trị CSDL:

Hệ quản trị CSDL là phần vô cùng quan trọng trong quá trình lập trình. Microsoft đã phát triển nhiều những phần mềm giúp ta xây dựng CSDL, tôi xin được chia sẻ với bạn ở bên dưới.
a. SQL Server 2005:
Bước 1: Cài phần mềm http://www.microsoft.com/downloads/en/details.aspx?FamilyId=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&displaylang=en

Bước 2: Cài thêm http://go.microsoft.com/fwlink/?linkid=65109

b. SQL Server 2008:

SQL Server 2008 có nhiều phiên bản khác nhau, trong đó bản Express   là  bản thấp nhất, được Microsoft cung cấp miễn phí cho người dùng với   mục  đích học tập và ứng dụng vào những ứng dụng nhỏ, không yêu cầu  cao  về  các tính năng khác ngoài việc lưu trữ và xử lý đơn giản.

Yêu cầu về phần cứng và hệ điều hành sử dụng:– Hệ điều hành tối thiểu: Windows XP SP3, Windows Wista SP1, Windows 7, Windows 2003 SP2.
Phần cứng: Pentium IV 2Gb MHz trở lên. Tối thiểu  1 GB RAM. Ổ cứng 10 GB.

Link Download :
– Để cài đặt SQL Server 2008 Express download về tại địa chỉ:
http://www.microsoft.com/en-us/download/details.aspx?id=1695

Để cài đặt SQL Server 2008 Express with management tools download về tại địa chỉ:
http://www.microsoft.com/en-us/download/details.aspx?id=22973

Đối với WinXp bắt buộc phải cài thêm: Bạn phải có Windows PowerShell 1.0
http://go.microsoft.com/fwlink/?LinkId=120552

Ngoài ra: Nếu máy đã cài xong VS2010 thì chỉ cần cài: Microsoft SQL Server 2008 Management Studio Express
tại địa chỉ: http://www.microsoft.com/en-us/download/details.aspx?id=7593

 

Chú ý : đối với máy tính cài Windows XP, khi cài SQL Express 2008, nó sẽ thường báo lỗi máy tính phải có cài .Net Framework 2.0 SP2 và  Windows Installer 4.5 rồi nó mới cho cài SQL Express 2008. Thì các bạn phải down Net framework 2.0 sp2Windows Installer 4.5 ở link trên về cài đặt xong rồi mới cài Sql Express 2008.
Các bước cài đặt :
Bước 1 : Tại màn hình cài đặt SQL Server 2008 bạn chọn mục Installation sau đó chọn New SQL Server stand-alone installation or add features to an existing installation

– Bước 2 : Tại màn hình Setup Support Rules  chọn OK

Bước 3 : Tại màn hình “Product Key“, chọn Next để tiếp tục

– Bước 4 : Tại màn hình License Term, đánh dấu chọn nút “I accept the licence terms”, rồi chọn “Next”

Bước 5 : Tại màn hình “setup support files”  nhấn nút “install” để tiếp tục.

Bước 6 : tại màn hình “Setup Support Rules“, nếu mỗi thứ suôn sẽ, thì nhấn nút “Next” để tiếp tục.

Bước 7 : Trên màn hình “features selection“, nhất nút “Sellect All” để chọn tất cả, sau đó nhấn nút “Next“.

Bước 8 : tại màn hình “instance Configuratio”, có 2 lựa chọn : chọn như hình dưới, rồi nhấn nút Next để tiếp tục ….

Bước 9 : Chọn Next để tiếp tục.

Bước 10 : Chọn “Account Name” và chọn là NT AUTHORITY\NETWORK như trong hình sau đây, sau đó nhấn Next để tiếp tục.

Bước 11 : Trên màn hình “Database Engine Configuration“, trong phần Account Provisioning, ta chọn “Windows Authotication Mode” hoặc “Mixed Mode” đều được cả
+ Chọn “Windows Authotication Mode” không cần nhập PassWord, để đơn giản ta nên chọn “Windows Authotication Mode
+ Chọn “Mixed Mode” thì ta phải nhập PassWord.
+ Sau cùng ta nhấn vào nút “Add Current User“, rồi nhấn nút Next để tiếp tục.

Bước 12 : nhấn nút “Next” để tiếp tục

Bước 13 : nhấn nút “Next” để tiếp tục

Bước 14 : nhấn nút “Install” để tiến hành cài đặt, quá trình cài đặt khoảng 3 phút …

Bước 15 : Nhấn nút “Next” để hoàn thành quá trình cài đặt. Cuối cùng cũng xong

[Lập trình Android] Tạo một Password ngẫu nhiên

Đầu tiên, tạo một ứng dụng Android và đặt tên là GenerateRandomPassword với Activity chính là MainActivity.
Chúng ta cần một class để xây dựng mật khẩu. Tạo class RandomPasswordGenerator với nội dung sau

public class RandomPasswordGenerator {

	private static final String ALPHA_CAPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz";
	private static final String NUM = "0123456789";
	private static final String SPL_CHARS = "!@#$%^&*_=+-/";

	public static char[] generatePswd(int minLen, int maxLen,
			int noOfCAPSAlpha, int noOfDigits, int noOfSplChars) {
		if (minLen > maxLen)
			throw new IllegalArgumentException("Min. Length > Max. Length!");
		if ((noOfCAPSAlpha + noOfDigits + noOfSplChars) > minLen)
			throw new IllegalArgumentException(
					"Min. Length should be atleast sum of (CAPS, DIGITS, SPL CHARS) Length!");
		Random rnd = new Random();
		int len = rnd.nextInt(maxLen - minLen + 1) + minLen;
		char[] pswd = new char[len];
		int index = 0;
		for (int i = 0; i < noOfCAPSAlpha; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = ALPHA_CAPS.charAt(rnd.nextInt(ALPHA_CAPS.length()));
		}
		for (int i = 0; i < noOfDigits; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = NUM.charAt(rnd.nextInt(NUM.length()));
		}
		for (int i = 0; i < noOfSplChars; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = SPL_CHARS.charAt(rnd.nextInt(SPL_CHARS.length()));
		}
		for (int i = 0; i < len; i++) {
			if (pswd[i] == 0) {
				pswd[i] = ALPHA.charAt(rnd.nextInt(ALPHA.length()));
			}
		}
		return pswd;
	}

	private static int getNextIndex(Random rnd, int len, char[] pswd) {
		int index = rnd.nextInt(len);
		while (pswd[index = rnd.nextInt(len)] != 0)
			;
		return index;
	}

}

Class này chứa một phương thức staticgeneratePswd() với 5 tham số truyền vào:
minLen - tối thiểu số ký tự
maxLen - tối đa số ký tự
noOfCAPSAlpha - số lượng ký tự in hoa
noOfDigits - số lượng ký tự là số
noOfSplChars - số lượng ký tự đặc biệt
Tiếp theo, chỉnh sửa lại layout cho MainActivity như sau



    


Chúng ta sử dụng TextView để hiển thị kết quả các mật khẩu được tạo.
Cuối cùng là chỉnh sửa lại MainActivity để tạo 10 mật khẩu ngẫu nhiên dùng class RandomPasswordGenerator

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		TextView txt = (TextView) findViewById(R.id.txt);

		int noOfCAPSAlpha = 1;
		int noOfDigits = 1;
		int noOfSplChars = 1;
		int minLen = 8;
		int maxLen = 12;

		String res = "";
		for (int i = 0; i < 10; i++) {
			char[] pswd = RandomPasswordGenerator.generatePswd(minLen, maxLen,
					noOfCAPSAlpha, noOfDigits, noOfSplChars);
			res += "Len = " + pswd.length + ", " + new String(pswd) + "n";
		}

		txt.setText(res);
	}
}

Các password được tạo ra trong mỗi lần chạy ứng dụng sẽ khác nhau.

[Lập trình Android] Hướng dẫn giải nén một tập tin *.zip tải từ Internet trong ứng dụng Android

Đầu tiên, tạo một ứng dụng Android và đặt tên là UnzipFile với Activity chính là MainActivity.
Chúng ta bắt đầu bằng việc thêm permission cho ứng dụng. Mở tập tin Android Manifest, thêm vào 2 permission sau

    
    

Quyền truy cập Internet để download tập tin *.zip về, sau đó sử dụng quyền ghi lên bộ nhớ ngoài để giải nén được tập tin.
Tiếp theo, chúng ta cần một class để giải nén tập tin. Tạo một class mới đặt tên là UnzipUtil, với nội dung sau

public class UnzipUtil {
	private String _zipFile;
	private String _location;

	public UnzipUtil(String zipFile, String location) {
		_zipFile = zipFile;
		_location = location;
		_dirChecker("");
	}

	public void unzip() {
		try {
			FileInputStream fin = new FileInputStream(_zipFile);
			ZipInputStream zin = new ZipInputStream(fin);
			ZipEntry ze = null;
			while ((ze = zin.getNextEntry()) != null) {
				if (ze.isDirectory()) {
					_dirChecker(ze.getName());
				} else {
					FileOutputStream fout = new FileOutputStream(_location
							+ ze.getName());
					byte[] buffer = new byte[8192];
					int len;
					while ((len = zin.read(buffer)) != -1) {
						fout.write(buffer, 0, len);
					}
					fout.close();
					zin.closeEntry();
				}
			}
			zin.close();
		} catch (Exception e) {
			Log.e("Decompress", "unzip", e);
		}
	}

	private void _dirChecker(String dir) {
		File f = new File(_location + dir);
		if (!f.isDirectory()) {
			f.mkdirs();
		}
	}
}

Chúng ta sẽ sử dụng class này để giải nén một tập tin *.zip từ đường dẫn zipFile vào trong thư mục có đường dẫn location.
Tiếp theo, ta chỉnh sửa lại MainActivity để thực hiện việc download và giải nén *.zip.
Đầu tiên, ta khai báo một số biến cần dùng cho ứng dụng

	private ProgressDialog mProgressDialog;
	String unzipLocation = Environment.getExternalStorageDirectory() + "/";
	String zipFile = Environment.getExternalStorageDirectory()
			+ "/download.zip";

Giả sử ta sẽ download tập tin *.zip từ đường dẫn: http://yeulaptrinh.vn/demo/down.zip
Tiếp theo, trong onCreate của MainActivity, chúng ta sẽ chạy một AsyncTask để download *.zip

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		DownloadMapAsync mew = new DownloadMapAsync();
		mew.execute("http://yeulaptrinh.vn/demo/down.zip");
	}

Nội dung của DownloadMapAsync như sau

	class DownloadMapAsync extends AsyncTask {
		boolean result;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mProgressDialog = new ProgressDialog(MainActivity.this);
			mProgressDialog.setMessage("Downloading Zip File..");
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();
		}

		@Override
		protected Void doInBackground(String... aurl) {
			int count;
			try {
				URL url = new URL(aurl[0]);
				URLConnection conexion = url.openConnection();
				conexion.connect();
				int lenghtOfFile = conexion.getContentLength();
				InputStream input = new BufferedInputStream(url.openStream());
				OutputStream output = new FileOutputStream(zipFile);
				byte data[] = new byte[1024];
				long total = 0;
				while ((count = input.read(data)) != -1) {
					total += count;
					publishProgress("" + (int) ((total * 100) / lenghtOfFile));
					output.write(data, 0, count);
				}
				output.close();
				input.close();
				result = true;
			} catch (Exception e) {
				result = false;
			}
			return null;
		}

		protected void onProgressUpdate(String... progress) {
			mProgressDialog.setProgress(Integer.parseInt(progress[0]));
		}

		@Override
		protected void onPostExecute(Void params) {
			mProgressDialog.dismiss();
			if (result) {
				new UnZipTask().execute();
			} else {
				Toast.makeText(MainActivity.this, "Download failed",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

Sau khi download xong tập tin vào trong đường dẫn zipFile, chúng ta sẽ tiếp tục cho chạy một AsyncTask khác để giải nén tập tin, đó là

new UnZipTask().execute();

Nội dung UnZipTask như sau:

	private class UnZipTask extends AsyncTask {

		@Override
		protected void onPreExecute() {
			mProgressDialog = new ProgressDialog(MainActivity.this);
			mProgressDialog
					.setMessage("Please Wait...Extracting zip file ... ");
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				UnzipUtil d = new UnzipUtil(zipFile, unzipLocation);
				d.unzip();
			} catch (Exception e) {
				return false;
			}
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			mProgressDialog.dismiss();
			if (!result) {
				Toast.makeText(MainActivity.this, "Unzip failed",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

Chúng ta sử dụng class UnzipUtil đã tạo ở trên để giải nén

				UnzipUtil d = new UnzipUtil(zipFile, unzipLocation);
				d.unzip();

Nếu sử dụng máy ảo để chạy thử ứng dụng, bạn mở phần quản lý File của máy ảo sẽ thấy tập tin down.zip được download và các tập tin giải nén từ down.zip.

[Android] Chèn ảnh động *.gif trong Android

Tạo một ứng dụng Android và đặt tên là AnimationGif với Activity chính là MainActivity.
Tiếp theo, ta copy một hình ảnh có định dạng *.gif vào trong thư mục /assets. Ở đây mình sẽ sử dụng tập tin test.gif.

Cách 1: Sử dụng GifDecoderView

Để hiển thị được ảnh dạng *.gif, chúng ta sẽ sử dụng một custom view có tên là GifDecoderView, và cần một class để decode tập tin *.gif, có tên là GifDecoder.


GifDecoder.java

public class GifDecoder {
        /**
         * File read status: No errors.
         */
        public static final int STATUS_OK = 0;
        /**
         * File read status: Error decoding file (may be partially decoded)
         */
        public static final int STATUS_FORMAT_ERROR = 1;
        /**
         * File read status: Unable to open source.
         */
        public static final int STATUS_OPEN_ERROR = 2;
        /** max decoder pixel stack size */
        protected static final int MAX_STACK_SIZE = 4096;
        protected InputStream in;
        protected int status;
        protected int width; // full image width
        protected int height; // full image height
        protected boolean gctFlag; // global color table used
        protected int gctSize; // size of global color table
        protected int loopCount = 1; // iterations; 0 = repeat forever
        protected int[] gct; // global color table
        protected int[] lct; // local color table
        protected int[] act; // active color table
        protected int bgIndex; // background color index
        protected int bgColor; // background color
        protected int lastBgColor; // previous bg color
        protected int pixelAspect; // pixel aspect ratio
        protected boolean lctFlag; // local color table flag
        protected boolean interlace; // interlace flag
        protected int lctSize; // local color table size
        protected int ix, iy, iw, ih; // current image rectangle
        protected int lrx, lry, lrw, lrh;
        protected Bitmap image; // current frame
        protected Bitmap lastBitmap; // previous frame
        protected byte[] block = new byte[256]; // current data block
        protected int blockSize = 0; // block size last graphic control extension info
        protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
        protected int lastDispose = 0;
        protected boolean transparency = false; // use transparent color
        protected int delay = 0; // delay in milliseconds
        protected int transIndex; // transparent color index
        // LZW decoder working arrays
        protected short[] prefix;
        protected byte[] suffix;
        protected byte[] pixelStack;
        protected byte[] pixels;
        protected Vector frames; // frames read from current file
        protected int frameCount;

        private static class GifFrame {
                public GifFrame(Bitmap im, int del) {
                        image = im;
                        delay = del;
                }

                public Bitmap image;
                public int delay;
        }

        /**
         * Gets display duration for specified frame.
         *
         * @param n
         *          int index of frame
         * @return delay in milliseconds
         */
        public int getDelay(int n) {
                delay = -1;
                if ((n >= 0) && (n < frameCount)) {
                        delay = frames.elementAt(n).delay;
                }
                return delay;
        }

        /**
         * Gets the number of frames read from file.
         *
         * @return frame count
         */
        public int getFrameCount() {
                return frameCount;
        }

        /**
         * Gets the first (or only) image read.
         *
         * @return BufferedBitmap containing first frame, or null if none.
         */
        public Bitmap getBitmap() {
                return getFrame(0);
        }

        /**
         * Gets the "Netscape" iteration count, if any. A count of 0 means repeat indefinitiely.
         *
         * @return iteration count if one was specified, else 1.
         */
        public int getLoopCount() {
                return loopCount;
        }

        /**
         * Creates new frame image from current data (and previous frames as specified by their disposition codes).
         */
        protected void setPixels() {
                // expose destination image's pixels as int array
                int[] dest = new int[width * height];
                // fill in starting image contents based on last image's dispose code
                if (lastDispose > 0) {
                        if (lastDispose == 3) {
                                // use image before last
                                int n = frameCount - 2;
                                if (n > 0) {
                                        lastBitmap = getFrame(n - 1);
                                } else {
                                        lastBitmap = null;
                                }
                        }
                        if (lastBitmap != null) {
                                lastBitmap.getPixels(dest, 0, width, 0, 0, width, height);
                                // copy pixels
                                if (lastDispose == 2) {
                                        // fill last image rect area with background color
                                        int c = 0;
                                        if (!transparency) {
                                                c = lastBgColor;
                                        }
                                        for (int i = 0; i < lrh; i++) {
                                                int n1 = (lry + i) * width + lrx;
                                                int n2 = n1 + lrw;
                                                for (int k = n1; k < n2; k++) {
                                                        dest[k] = c;
                                                }
                                        }
                                }
                        }
                }
                // copy each source line to the appropriate place in the destination
                int pass = 1;
                int inc = 8;
                int iline = 0;
                for (int i = 0; i < ih; i++) {
                        int line = i;
                        if (interlace) {
                                if (iline >= ih) {
                                        pass++;
                                        switch (pass) {
                                        case 2:
                                                iline = 4;
                                                break;
                                        case 3:
                                                iline = 2;
                                                inc = 4;
                                                break;
                                        case 4:
                                                iline = 1;
                                                inc = 2;
                                                break;
                                        default:
                                                break;
                                        }
                                }
                                line = iline;
                                iline += inc;
                        }
                        line += iy;
                        if (line < height) {
                                int k = line * width;
                                int dx = k + ix; // start of line in dest
                                int dlim = dx + iw; // end of dest line
                                if ((k + width) < dlim) {
                                        dlim = k + width; // past dest edge
                                }
                                int sx = i * iw; // start of line in source
                                while (dx < dlim) {
                                        // map color and insert in destination
                                        int index = ((int) pixels[sx++]) & 0xff;
                                        int c = act[index];
                                        if (c != 0) {
                                                dest[dx] = c;
                                        }
                                        dx++;
                                }
                        }
                }
                image = Bitmap.createBitmap(dest, width, height, Config.ARGB_4444);
        }

        /**
         * Gets the image contents of frame n.
         *
         * @return BufferedBitmap representation of frame, or null if n is invalid.
         */
        public Bitmap getFrame(int n) {
                if (frameCount <= 0)
                        return null;
                n = n % frameCount;
                return ((GifFrame) frames.elementAt(n)).image;
        }

        /**
         * Reads GIF image from stream
         *
         * @param is
         *          containing GIF file.
         * @return read status code (0 = no errors)
         */
        public int read(InputStream is) {
                init();
                if (is != null) {
                        in = is;
                        readHeader();
                        if (!err()) {
                                readContents();
                                if (frameCount < 0) {
                                        status = STATUS_FORMAT_ERROR;
                                }
                        }
                } else {
                        status = STATUS_OPEN_ERROR;
                }
                try {
                        is.close();
                } catch (Exception e) {
                }
                return status;
        }

        /**
         * Decodes LZW image data into pixel array. Adapted from John Cristy's BitmapMagick.
         */
        protected void decodeBitmapData() {
                int nullCode = -1;
                int npix = iw * ih;
                int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;
                if ((pixels == null) || (pixels.length < npix)) {
                        pixels = new byte[npix]; // allocate new pixel array
                }
                if (prefix == null) {
                        prefix = new short[MAX_STACK_SIZE];
                }
                if (suffix == null) {
                        suffix = new byte[MAX_STACK_SIZE];
                }
                if (pixelStack == null) {
                        pixelStack = new byte[MAX_STACK_SIZE + 1];
                }
                // Initialize GIF data stream decoder.
                data_size = read();
                clear = 1 << data_size;
                end_of_information = clear + 1;
                available = clear + 2;
                old_code = nullCode;
                code_size = data_size + 1;
                code_mask = (1 << code_size) - 1;
                for (code = 0; code < clear; code++) {
                        prefix[code] = 0;
                        suffix[code] = (byte) code;
                }
                // Decode GIF pixel stream.
                datum = bits = count = first = top = pi = bi = 0;
                for (i = 0; i < npix;) {
                        if (top == 0) {
                                if (bits < code_size) {
                                        // Load bytes until there are enough bits for a code.
                                        if (count == 0) {
                                                // Read a new data block.
                                                count = readBlock();
                                                if (count <= 0) {
                                                        break;
                                                }
                                                bi = 0;
                                        }
                                        datum += (((int) block[bi]) & 0xff) << bits;
                                        bits += 8;
                                        bi++;
                                        count--;
                                        continue;
                                }
                                // Get the next code.
                                code = datum & code_mask;
                                datum >>= code_size;
                                bits -= code_size;
                                // Interpret the code
                                if ((code > available) || (code == end_of_information)) {
                                        break;
                                }
                                if (code == clear) {
                                        // Reset decoder.
                                        code_size = data_size + 1;
                                        code_mask = (1 << code_size) - 1;
                                        available = clear + 2;
                                        old_code = nullCode;
                                        continue;
                                }
                                if (old_code == nullCode) {
                                        pixelStack[top++] = suffix[code];
                                        old_code = code;
                                        first = code;
                                        continue;
                                }
                                in_code = code;
                                if (code == available) {
                                        pixelStack[top++] = (byte) first;
                                        code = old_code;
                                }
                                while (code > clear) {
                                        pixelStack[top++] = suffix[code];
                                        code = prefix[code];
                                }
                                first = ((int) suffix[code]) & 0xff;
                                // Add a new string to the string table,
                                if (available >= MAX_STACK_SIZE) {
                                        break;
                                }
                                pixelStack[top++] = (byte) first;
                                prefix[available] = (short) old_code;
                                suffix[available] = (byte) first;
                                available++;
                                if (((available & code_mask) == 0) && (available < MAX_STACK_SIZE)) {
                                        code_size++;
                                        code_mask += available;
                                }
                                old_code = in_code;
                        }
                        // Pop a pixel off the pixel stack.
                        top--;
                        pixels[pi++] = pixelStack[top];
                        i++;
                }
                for (i = pi; i < npix; i++) {
                        pixels[i] = 0; // clear missing pixels
                }
        }

        /**
         * Returns true if an error was encountered during reading/decoding
         */
        protected boolean err() {
                return status != STATUS_OK;
        }

        /**
         * Initializes or re-initializes reader
         */
        protected void init() {
                status = STATUS_OK;
                frameCount = 0;
                frames = new Vector();
                gct = null;
                lct = null;
        }

        /**
         * Reads a single byte from the input stream.
         */
        protected int read() {
                int curByte = 0;
                try {
                        curByte = in.read();
                } catch (Exception e) {
                        status = STATUS_FORMAT_ERROR;
                }
                return curByte;
        }

        /**
         * Reads next variable length block from input.
         *
         * @return number of bytes stored in "buffer"
         */
        protected int readBlock() {
                blockSize = read();
                int n = 0;
                if (blockSize > 0) {
                        try {
                                int count = 0;
                                while (n < blockSize) {
                                        count = in.read(block, n, blockSize - n);
                                        if (count == -1) {
                                                break;
                                        }
                                        n += count;
                                }
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        if (n < blockSize) {
                                status = STATUS_FORMAT_ERROR;
                        }
                }
                return n;
        }

        /**
         * Reads color table as 256 RGB integer values
         *
         * @param ncolors
         *          int number of colors to read
         * @return int array containing 256 colors (packed ARGB with full alpha)
         */
        protected int[] readColorTable(int ncolors) {
                int nbytes = 3 * ncolors;
                int[] tab = null;
                byte[] c = new byte[nbytes];
                int n = 0;
                try {
                        n = in.read(c);
                } catch (Exception e) {
                        e.printStackTrace();
                }
                if (n < nbytes) {
                        status = STATUS_FORMAT_ERROR;
                } else {
                        tab = new int[256]; // max size to avoid bounds checks
                        int i = 0;
                        int j = 0;
                        while (i < ncolors) {
                                int r = ((int) c[j++]) & 0xff;
                                int g = ((int) c[j++]) & 0xff;
                                int b = ((int) c[j++]) & 0xff;
                                tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
                        }
                }
                return tab;
        }

        /**
         * Main file parser. Reads GIF content blocks.
         */
        protected void readContents() {
                // read GIF file content blocks
                boolean done = false;
                while (!(done || err())) {
                        int code = read();
                        switch (code) {
                        case 0x2C: // image separator
                                readBitmap();
                                break;
                        case 0x21: // extension
                                code = read();
                                switch (code) {
                                case 0xf9: // graphics control extension
                                        readGraphicControlExt();
                                        break;
                                case 0xff: // application extension
                                        readBlock();
                                        String app = "";
                                        for (int i = 0; i < 11; i++) {
                                                app += (char) block[i];
                                        }
                                        if (app.equals("NETSCAPE2.0")) {
                                                readNetscapeExt();
                                        } else {
                                                skip(); // don't care
                                        }
                                        break;
                                case 0xfe:// comment extension
                                        skip();
                                        break;
                                case 0x01:// plain text extension
                                        skip();
                                        break;
                                default: // uninteresting extension
                                        skip();
                                }
                                break;
                        case 0x3b: // terminator
                                done = true;
                                break;
                        case 0x00: // bad byte, but keep going and see what happens break;
                        default:
                                status = STATUS_FORMAT_ERROR;
                        }
                }
        }

        /**
         * Reads Graphics Control Extension values
         */
        protected void readGraphicControlExt() {
                read(); // block size
                int packed = read(); // packed fields
                dispose = (packed & 0x1c) >> 2; // disposal method
                if (dispose == 0) {
                        dispose = 1; // elect to keep old image if discretionary
                }
                transparency = (packed & 1) != 0;
                delay = readShort() * 10; // delay in milliseconds
                transIndex = read(); // transparent color index
                read(); // block terminator
        }

        /**
         * Reads GIF file header information.
         */
        protected void readHeader() {
                String id = "";
                for (int i = 0; i < 6; i++) {
                        id += (char) read();
                }
                if (!id.startsWith("GIF")) {
                        status = STATUS_FORMAT_ERROR;
                        return;
                }
                readLSD();
                if (gctFlag && !err()) {
                        gct = readColorTable(gctSize);
                        bgColor = gct[bgIndex];
                }
        }

        /**
         * Reads next frame image
         */
        protected void readBitmap() {
                ix = readShort(); // (sub)image position & size
                iy = readShort();
                iw = readShort();
                ih = readShort();
                int packed = read();
                lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace
                lctSize = (int) Math.pow(2, (packed & 0x07) + 1);
                // 3 - sort flag
                // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color
                // table size
                interlace = (packed & 0x40) != 0;
                if (lctFlag) {
                        lct = readColorTable(lctSize); // read table
                        act = lct; // make local table active
                } else {
                        act = gct; // make global table active
                        if (bgIndex == transIndex) {
                                bgColor = 0;
                        }
                }
                int save = 0;
                if (transparency) {
                        save = act[transIndex];
                        act[transIndex] = 0; // set transparent color if specified
                }
                if (act == null) {
                        status = STATUS_FORMAT_ERROR; // no color table defined
                }
                if (err()) {
                        return;
                }
                decodeBitmapData(); // decode pixel data
                skip();
                if (err()) {
                        return;
                }
                frameCount++;
                // create new image to receive frame data
                image = Bitmap.createBitmap(width, height, Config.ARGB_4444);
                setPixels(); // transfer pixel data to image
                frames.addElement(new GifFrame(image, delay)); // add image to frame
                // list
                if (transparency) {
                        act[transIndex] = save;
                }
                resetFrame();
        }

        /**
         * Reads Logical Screen Descriptor
         */
        protected void readLSD() {
                // logical screen size
                width = readShort();
                height = readShort();
                // packed fields
                int packed = read();
                gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
                // 2-4 : color resolution
                // 5 : gct sort flag
                gctSize = 2 << (packed & 7); // 6-8 : gct size
                bgIndex = read(); // background color index
                pixelAspect = read(); // pixel aspect ratio
        }

        /**
         * Reads Netscape extenstion to obtain iteration count
         */
        protected void readNetscapeExt() {
                do {
                        readBlock();
                        if (block[0] == 1) {
                                // loop count sub-block
                                int b1 = ((int) block[1]) & 0xff;
                                int b2 = ((int) block[2]) & 0xff;
                                loopCount = (b2 << 8) | b1;
                        }
                } while ((blockSize > 0) && !err());
        }

        /**
         * Reads next 16-bit value, LSB first
         */
        protected int readShort() {
                // read 16-bit value, LSB first
                return read() | (read() << 8);
        }

        /**
         * Resets frame state for reading next image.
         */
        protected void resetFrame() {
                lastDispose = dispose;
                lrx = ix;
                lry = iy;
                lrw = iw;
                lrh = ih;
                lastBitmap = image;
                lastBgColor = bgColor;
                dispose = 0;
                transparency = false;
                delay = 0;
                lct = null;
        }

        /**
         * Skips variable length blocks up to and including next zero length block.
         */
        protected void skip() {
                do {
                        readBlock();
                } while ((blockSize > 0) && !err());
        }
}

GifDecoderView.java

public class GifDecoderView extends ImageView {

	public GifDecoderView(Context context) {
		super(context);
	}

	public GifDecoderView(Context context, InputStream stream) {
		super(context);
		playGif(stream);
	}

	private boolean mIsPlayingGif = false;

	private GifDecoder mGifDecoder;

	private Bitmap mTmpBitmap;

	final Handler mHandler = new Handler();

	final Runnable mUpdateResults = new Runnable() {
		public void run() {
			if (mTmpBitmap != null && !mTmpBitmap.isRecycled()) {
				GifDecoderView.this.setImageBitmap(mTmpBitmap);
			}
		}
	};

	private void playGif(InputStream stream) {
		mGifDecoder = new GifDecoder();
		mGifDecoder.read(stream);

		mIsPlayingGif = true;

		new Thread(new Runnable() {
			public void run() {
				final int n = mGifDecoder.getFrameCount();
				final int ntimes = mGifDecoder.getLoopCount();
				int repetitionCounter = 0;
				do {
					for (int i = 0; i < n; i++) {
						mTmpBitmap = mGifDecoder.getFrame(i);
						int t = mGifDecoder.getDelay(i);
						mHandler.post(mUpdateResults);
						try {
							Thread.sleep(t);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					if (ntimes != 0) {
						repetitionCounter++;
					}
				} while (mIsPlayingGif && (repetitionCounter <= ntimes));
			}
		}).start();
	}

	public void stopRendering() {
		mIsPlayingGif = true;
	}
}

Tiếp theo, ta chỉnh sửa MainActivity để hiển thị tập tin test.gif.
Chúng ta đọc tập tin test.gif vào trong một InputStream

		InputStream stream = null;
		try {
			stream = getAssets().open("test.gif");
		} catch (IOException e) {
			e.printStackTrace();
		}

Sau đó khởi tạo một GifDecoderView với tham số là InputStream vừa có như sau

		GifDecoderView view = new GifDecoderView(this, stream);

Cuối cùng là gán nội dung vào view của Activity để hiển thị:

		setContentView(view);

Cách 2: Sử dụng GifWebView

Cách này, chúng ta sẽ sử dụng GifWebView. Thực tế, ở đây ta sử dụng WebView, chỉ là custom lại để hiển thị ảnh từ đường dẫn đưa vào.
Tạo một class GifWebView với nội dung sau.

public class GifWebView extends WebView {

	public GifWebView(Context context, String path) {
		super(context);
		loadUrl(path);
	}
}

Sau đó, chỉnh sửa lại MainActivity. Chúng ta chỉ cần một đoạn mã sau để hiển thị test.gif

		GifWebView view = new GifWebView(this,"file:///android_asset/test.gif");

Và gán view này để hiển thị trên thiết bị:

		setContentView(view);

Đọc dữ liệu từ file text trong Java

Trước khi học bài này bạn nên đọc lại bài:

Để hiểu rõ về cách Java đọc dữ liệu một chút vì nó rất quan trọng nếu bạn không hiểu rõ cái này thì sẽ mãi không làm chủ được Java đâu 🙂

Tổng quan

doc-du-lieu-yeulaptrinh.pw

Các luồng và class trong I/O file text

Nhắc lại nguyên lý đọc dữ liệu trong Java một chút: các thiết bị vào ra (bàn phím, màn hình…) qua luồng rồi ta mới nhận được thông tin.

 luong-trong-doc-file-yeulaptrinh.pwSử dụng BufferedReader BufferedWriter

Đọc, ghi file với BufferedReader và BufferedWriter là cách đọc nhanh nhất trong Java, ngoài ra nó còn có nhiều tính năng có sẵn kèm theo như: đọc cả dòng, encoding… Có nhiều cách đọc, ghi file nhưng mình khuyên các bạn nên dùng cách này dù nó có dài hơn một chút (code bên dưới).

import java.io.*;
import java.util.*;

public class ReadTest2
{
	static long total = 0;

	private static void ReadLines() {
		try {
			String s = "";
			BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
			while (stdin.ready()) {
				s = stdin.readLine();
				for (int i=0; i

Sử dụng FileReader và FileWriter

Thằng này thì không hỗ trợ đọc từng dòng, mã hóa và nó làm việc với bảng mã mặc định của hệ thống nên nó không phải là cách tốt để đọc và ghi file.

static void copyFile(FileReader inputFile, FileWriter outputFile) {
try{
  // Read the first character.
  int nextChar = inputFile.read();
  // Have we reached the end of file?
  while(nextChar != -1) {
    outputFile.write(nextChar);
    // Read the next character.
    nextChar = inputFile.read();
  }
  outputFile.flush();
}
catch(IOException e) {  System.out.println("Unable to copy file");
}
}