GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Java I/O Hướng dẫn sử dụng luồng vào ra ký tự trong Java

Hướng dẫn sử dụng luồng vào ra ký tự trong Java

Đăng vào 13/12/2017 . Được đăng bởi GP Coder . 14127 Lượt xem . Toàn màn hình

Trong bài học trước tôi đã giới thiệu về luồng vào ra nhị phân (input-output binary stream), trong bài này chúng ta tiếp tục tìm hiểu về luồng vào ra ký tự (input-output character stream) trong Java. Như bạn đã biết uồng nhị phân (binary stream), mỗi một lần đọc/ghi một byte (Tương đương với 8 bit), trong khi đó luồng ký tự (character stream) mỗi lần đọc/ghi một ký tự, tùy thuộc vào kiểu mã hóa (encoding) ( UTF-8, UTF-16,..) mà ký tự đó tương đương với 1, 2 hoặc 3 byte.

Trong Java, có nhiều lớp hỗ trợ các thao tác với luồng ký tự và các lớp này được dẫn đầu bởi 2 class Reader và Writer:

  • java.io.Reader: được sử dụng để đọc dữ liệu từ một nguồn (source).
  • java.io.Writer: được sử dụng để ghi dữ liệu đến đích (destination).

Nội dung

  • 1 Đọc chuỗi từ console
  • 2 Sử dụng lớp FileReader và FileWriter
  • 3 Chuyển một luồng nhị phân thành luồng ký tự
  • 4 Sử dụng FilterInputStream và FilterOutputStream
  • 5 Sử dụng lớp BufferedReader và BufferedWriter
  • 6 Sử dụng lớp CharArrayReader và CharArrayWriter
  • 7 Ví dụ ghi một dữ liệu chung ra nhiều file
  • 8 Sử dụng lớp StringReader và StringWriter
  • 9 Ghi file với lớp PrintStream
  • 10 Ghi file với lớp PrintWriter
  • 11 Sử dụng lớp PushbackInputStream
  • 12 Sử dụng lớp PushbackReader
  • 13 Sử dụng lớp PipedReader và PipedWriter

Đọc chuỗi từ console

Ví dụ nhập một chuỗi từ bàn phím và hiển thị chuỗi ra màn hình


package com.gpcoder.characterstream;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadConsole {

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			System.out.print("Enter your name: ");
			String name = br.readLine();
			if (name.equalsIgnoreCase("Exit")) {
				System.out.println("Finished!");
				break;
			}
			System.out.println("Hello " + name);
		}
	}
}

Kết quả thực thi chương trình trên:


Enter your name: gpcoder.com
Hello gpcoder.com
Enter your name: exit
Finished!

Sử dụng lớp FileReader và FileWriter

Ví dụ ghi file sử dụng lớp FileWriter


import java.io.FileWriter;

public interface FileWriterExample {
	public static void main(String args[]) {
		try {
			FileWriter fw = new FileWriter("data/test.txt");
			fw.write("gpcoder.com");
			fw.close();
		} catch (Exception e) {
			System.out.println(e);
		}
		System.out.println("Success...");
	}
}

Thực thi chương trình trên, một file test.txt được tạo ra trong thư mục data với nội dung gpcoder.com

Ví dụ đọc file sử dụng lớp FileReader


package com.gpcoder.characterstream;

import java.io.FileReader;

public class FileReaderExample {
	public static void main(String args[]) throws Exception {
		FileReader fr = new FileReader("data/test.txt");
		int i;
		while ((i = fr.read()) != -1) {
			System.out.print((char) i);
		}
		fr.close();
	}
}

Kết quả thực thi chương trình trên:


gpcoder.com

Chuyển một luồng nhị phân thành luồng ký tự

Ví dụ chuyển từ OutputStream sang Writer


package com.gpcoder.characterstream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class OutputStreamWriterExample {

	public static void main(String[] args) throws IOException {

		// Tạo một OutputStream (luồng đầu ra) để ghi dữ liệu vào file.
		OutputStream out = new FileOutputStream("data/test.txt");

		// Tạo một Character Stream (luồng ghi ký tự) với mã hóa (encoding) là UTF-8.
		Writer writer = new OutputStreamWriter(out, "UTF-8");

		String s = "Lập trình Java";
		writer.write(s);
		writer.close();
	}
}

Ví dụ chuyển từ InputStream sang Reader


package com.gpcoder.characterstream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class InputStreamReaderExample {

	public static void main(String[] args) throws IOException {

		// Tạo một binary Stream (luồng nhị phân), để đọc file.
		InputStream in = new FileInputStream("data/test.txt");

		// Tạo một Character stream (luồng ký tự) với mã hóa (encoding) là UTF-8.
		Reader reader = new InputStreamReader(in, "UTF-8");

		int i = 0;
		// Đọc lần lượt từng ký tự.
		while ((i = reader.read()) != -1) {
			// Ép kiểu (cast) thành một ký tự và in ra màn hình.
			System.out.println((char) i + " " + i);
		}
		reader.close();
	}
}

Sử dụng FilterInputStream và FilterOutputStream

Lớp FilterOutputStream trong java extends lớp OutputStream. Nó cung cấp các lớp con khác nhau như BufferedOutputStream và DataOutputStream để cung cấp các chức năng bổ sung. Vì vậy, nó ít được sử dụng riêng lẻ.

Lớp FilterInputStream trong java extends lớp InputStream. Nó cung cấp các lớp con khác nhau như BufferedInputStream và DataInputStream để cung cấp chức năng bổ sung. Vì vậy, nó ít được sử dụng riêng lẻ.

Ví dụ ghi file sử dụng lớp FilterOutputStream


package com.gpcoder.characterstream;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;

public class FilterOutputStreamExample {
	public static void main(String[] args) throws IOException {
		FileOutputStream file = null;
		FilterOutputStream filter = null;
		try {
			file = new FileOutputStream(new File("data/test.txt"));
			filter = new FilterOutputStream(file);
			String s = "gpcoder.com";
			byte b[] = s.getBytes();
			filter.write(b);
			filter.flush();
			System.out.println("Success...");
		} finally {
			filter.close();
			file.close();
		}
	}
}

Ví dụ đọc file sử dụng lớp FilterInputStream


package com.gpcoder.characterstream;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.IOException;

public class FilterInputStreamExample {
	public static void main(String[] args) throws IOException {
		FileInputStream file = null;
		FilterInputStream filter = null;
		try {
			file = new FileInputStream(new File("data/test.txt"));
			filter = new BufferedInputStream(file);

			int k = 0;
			while ((k = filter.read()) != -1) {
				System.out.print((char) k);
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		file.close();
		filter.close();
	}
}

Sử dụng lớp BufferedReader và BufferedWriter

Lớp BufferedWriter trong java được sử dụng để cung cấp bộ đệm cho các các thể hiện của lớp Writer. Nó giúp hiệu suất nhanh. Nó thừa kế lớp Writer. Các ký tự đệm được sử dụng để cung cấp việc ghi dữ liệu hiệu quả với các mảng đơn, các ký tự và chuỗi.

Lớp BufferedReader trong java được sử dụng để đọc văn bản từ một input stream dựa trên các ký tự (character stream). Nó có thể được sử dụng để đọc dữ liệu theo dòng (line by line) bằng phương thức readLine(). Nó giúp hiệu suất nhanh. Nó kế thừa lớp Reader.

Ví dụ ghi file sử dụng BufferedWriter

package com.gpcoder.characterstream;

import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferedWriterExample {
	public static void main(String[] args) throws Exception {
		FileWriter writer = new FileWriter("data/test.txt");
		BufferedWriter buffer = new BufferedWriter(writer);
		buffer.write("gpcoder.com");
		buffer.close();
		System.out.println("Success...");
	}
}

Ví dụ đọc file sử dụng BufferedReader


package com.gpcoder.characterstream;

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferedReaderExample {
	public static void main(String args[]) throws Exception {
		FileReader fr = new FileReader("data/test.txt");
		BufferedReader br = new BufferedReader(fr);

		int i;
		while ((i = br.read()) != -1) {
			System.out.print((char) i);
		}
		br.close();
		fr.close();
	}
}

Sử dụng lớp CharArrayReader và CharArrayWriter

CharArrayReader gồm có hai từ: CharArray và Reader. Lớp CharArrayReader trong java được sử dụng để đọc mảng ký tự như là một trình đọc (Reader). Nó kế thừa lớp Reader.

Lớp CharArrayWriter trong java có thể được sử dụng để ghi dữ liệu chung cho nhiều file. Lớp này thừa kế lớp Writer. Bộ đệm của nó tự động phát triển khi dữ liệu được ghi vào stream này. Gọi phương thức close() đối với đối tượng này không có hiệu lực.

Ví dụ đọc một ký tự sử dụng lớp Java CharArrayReader


package com.gpcoder.characterstream;

import java.io.CharArrayReader;

public class CharArrayReaderExample {
	public static void main(String[] ag) throws Exception {
		char[] ary = { 'g', 'p', 'c', 'o', 'd', 'e', 'r', '.', 'c', 'o', 'm' };
		CharArrayReader reader = new CharArrayReader(ary);
		int k = 0;
		// Read until the end of a file
		while ((k = reader.read()) != -1) {
			char ch = (char) k;
			System.out.print(ch + " : ");
			System.out.println(k);
		}
	}
}

Kết quả thực thi chương trình trên:


g : 103
p : 112
c : 99
o : 111
d : 100
e : 101
r : 114
. : 46
c : 99
o : 111
m : 109

Ví dụ ghi một dữ liệu chung ra nhiều file


package com.gpcoder.characterstream;

import java.io.CharArrayWriter;
import java.io.FileWriter;

public class CharArrayWriterExample {
	public static void main(String args[]) throws Exception {
		CharArrayWriter out = new CharArrayWriter();
		out.write("gpcoder.com");
		FileWriter f1 = new FileWriter("data/f1.txt");
		FileWriter f2 = new FileWriter("data/f2.txt");
		FileWriter f3 = new FileWriter("data/f3.txt");
		FileWriter f4 = new FileWriter("data/f4.txt");
		out.writeTo(f1);
		out.writeTo(f2);
		out.writeTo(f3);
		out.writeTo(f4);
		f1.close();
		f2.close();
		f3.close();
		f4.close();
		System.out.println("Success...");
	}
}

Thực thi chương trình trên, 4 file f1.txt, f2.txt, f3.txt, f4.txt được tạo ra trong thư mục data và có cùng nội dung gpcoder.com

Sử dụng lớp StringReader và StringWriter

Lớp StringWriter trong java là một charater stream thu thập dữ liệu từ bộ đệm chuỗi, có thể được sử dụng để xây dựng một chuỗi. Lớp StringWriter kế thừa lớp Writer. Trong lớp StringWriter, các tài nguyên hệ thống như các network socket và file không được sử dụng, do đó việc đóng StringWriter là không cần thiết.

Lớp StringReader trong java là một character stream với chuỗi như một nguồn dữ liêu. Nó lấy một chuỗi đầu vào và thay đổi nó vào character stream. Nó kế thừa lớp Reader. Trong lớp StringReader, các tài nguyên hệ thống như các network socket và các file không được sử dụng, do đó việc đóng StringReader là không cần thiết.

Ví dụ StringWriter sử dụng BufferedReader để đọc file từ luồng (stream)


package com.gpcoder.characterstream;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;

public class StringWriterExample {
	public static void main(String[] args) throws IOException {
		char[] arr = new char[512];
		StringWriter writer = new StringWriter();
		FileInputStream input = null;
		BufferedReader buffer = null;
		input = new FileInputStream("data/test.txt");
		buffer = new BufferedReader(new InputStreamReader(input, "UTF-8"));
		int x;
		while ((x = buffer.read(arr)) != -1) {
			writer.write(arr, 0, x);
		}
		System.out.println(writer.toString());
		writer.close();
		buffer.close();
	}
}

Ví dụ StringReader đọc chuỗi như luồng ký tự (stream)

package com.gpcoder.characterstream;

import java.io.StringReader;

public class StringReaderExample {
	public static void main(String[] args) throws Exception {
		String srg = "gpcoder.com";
		StringReader reader = new StringReader(srg);
		int k = 0;
		while ((k = reader.read()) != -1) {
			System.out.print((char) k);
		}
	}
}

Ghi file với lớp PrintStream

Lớp PrintStream trong java cung cấp các phương thức để ghi dữ liệu vào một stream khác. Lớp PrintStream tự động làm sạch dữ liệu vì vậy không cần gọi phương thức flush(). Hơn nữa, các phương thức của nó không ném ngoại lệ IOException.


package com.gpcoder.characterstream;

import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamExample {
	public static void main(String args[]) throws Exception {
		FileOutputStream fout = new FileOutputStream("data/test.txt");
		PrintStream pout = new PrintStream(fout);
		pout.println(2017);
		pout.println("gpcoder.com");
		pout.println("Java I/O Tutorials");
		pout.close();
		fout.close();
		System.out.println("Success...");
	}
}

Ghi file với lớp PrintWriter

Lớp PrintWriter trong java là bản cài đặt của lớp Writer. Nó được sử dụng để ghi các định dạng đại diện của các đối tượng vào stream hướng văn bản.


package com.gpcoder.characterstream;

import java.io.File;
import java.io.PrintWriter;

public class PrintWriterExample {
	public static void main(String[] args) throws Exception {
		// Data to write on Console using PrintWriter
		PrintWriter writer = new PrintWriter(System.out);
		writer.write("Data to write on Console using PrintWriter");
		writer.flush();
		writer.close();

		// Data to write in File using PrintWriter
		PrintWriter writer1 = null;
		writer1 = new PrintWriter(new File("data/test.txt"));
		writer1.write("Data to write in File using PrintWriter");
		writer1.flush();
		writer1.close();
	}
}

Thực thi chương trình trên, một dòng chữ Data to write on Console using PrintWriter trong Console và một file test.txt được tạo ra trong thư mục data của project với nội dung Data to write in File using PrintWriter.

Sử dụng lớp PushbackInputStream

Lớp PushbackInputStream trong java ghi đè các phương thức của lớp InputStream và cung cấp thêm chức năng mở rộng cho một input stream khác. Nó có thể unread một byte đã được đọc và đẩy trở lại một byte.


package com.gpcoder.characterstream;

import java.io.ByteArrayInputStream;
import java.io.PushbackInputStream;

public class PushbackInputStreamExample {
	public static void main(String[] args) throws Exception {
		String srg = "1##2#34###12";
		byte[] byteArr = srg.getBytes();
		ByteArrayInputStream array = new ByteArrayInputStream(byteArr);
		PushbackInputStream push = new PushbackInputStream(array);
		int i;
		while ((i = push.read()) != -1) {
			// Tìm thấy ký tự '#'
			if (i == '#') {
				int j;
				// Đọc tiếp một ký tự nữa
				if ((j = push.read()) == '#') {
					System.out.print("**");
				} else {
					// Đẩy trở lại (Pushes back) ký tự này lên luồng.
					// Giống như lùi con trỏ trở lại 1 vị trí.
					push.unread(j);
					System.out.print((char) i);
				}
			} else {
				System.out.print((char) i);
			}
		}
	}
}

Kết quả thực thi chương trình trên:


1**2#34**#12

Sử dụng lớp PushbackReader

Lớp PushbackReader trong java ghi đè các phương thức của lớp FilterReader và cung cấp thêm các chức năng mở rộng. Nó được sử dụng để đọc một luồng ký tự và có thể đẩy trở lại một ký tự vào stream.


package com.gpcoder.characterstream;

import java.io.CharArrayReader;
import java.io.PushbackReader;

public class PushbackReaderExample {
	public static void main(String[] args) throws Exception {
		char ary[] = { '1', '-', '-', '2', '-', '3', '4', '-', '-', '-', '5', '6' };
		CharArrayReader reader = new CharArrayReader(ary);
		PushbackReader push = new PushbackReader(reader);
		int i;
		while ((i = push.read()) != -1) {
			// Tìm thấy ký tự '-'
			if (i == '-') {
				int j;
				// Đọc tiếp một ký tự nữa
				if ((j = push.read()) == '-') {
					System.out.print("#*");
				} else {
					// Đẩy trở lại (Pushes back) ký tự này lên luồng.
					// Giống như lùi con trỏ trở lại 1 vị trí.
					push.unread(j);
					System.out.print((char) i);
				}
			} else {
				System.out.print((char) i);
			}
		}
	}
}

Kết quả thực thi chương trình trên:


1#*2-34#*-56

Sử dụng lớp PipedReader và PipedWriter

Đặt ra một tình huống bạn có 2 luồng một luồng đầu vào và một luồng đầu ra. Chẳng hạn luồng dữ liệu đầu vào X đọc một file, lấy thông tin từ luồng này ghi vào luồng dữ liệu Y đầu ra là một file khác. Hai luồng X và Y trong tình huống này là tách riêng nhau. Vì vậy trong ứng dụng bạn phải có 3 thao tác:

  • Tạo luồng dữ liệu đọc X
  • Tạo luồng ghi dữ liệu Y
  • Đọc từ X ghi vào Y

Hai thao tác đầu phải có, nhưng bạn muốn bỏ đi thao tác thứ 3, nghĩa là có một cái gì đó liên hệ ngầm với nhau giữa 2 luồng ,để sao cho những ký tự xuất hiện trên luồng đầu đọc X lập tức luồng đầu ra Y biết được và đọc luôn các ký tự đó vào luồng của mình. Đó được gọi là liên hệ đường ngầm giữa 2 luồng vào và ra.

Điều này còn thực sự có ý nghĩa hơn khi biết rằng (với hiệu ứng đường ngầm này) khi luồng đầu ra khi đã đọc hết các ký tự trên luồng đầu vào nó tự động chờ đợi các ký tự nào đó xuất hiện trên luồng đầu vào và lại đọc hết vào luồng đầu ra.

Thật vậy hiệu ứng đường ngầm này chỉ sử dụng hiệu quả trong một vài tình huống không phải tất cả , và khi sử dụng nó thường được sử dụng đi đôi với xử lý đa luồng (Mulit-thread).

Ví dụ sử dụng PipedReader


package com.gpcoder.characterstream;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.Reader;

public class PipeReaderExample {
	private Reader pipedReader;

	public static void main(String[] args) throws IOException, InterruptedException {
		new PipeReaderExample().test();
	}

	private void test() throws IOException, InterruptedException {
		// Tạo một 'pipedWriter',
		PipedWriter pipedWriter = new PipedWriter();

		// Dữ liệu ghi vào 'pipedWriter'
		// sẽ tự động xuất hiện tại 'pipedReader'.
		pipedReader = new PipedReader(pipedWriter);

		new ThreadRead().start();

		char[] chs = new char[] { 'a', 'a', 'b', 'c', 'e' };

		// Ghi dữ liệu vào 'pipedWriter'.
		for (char ch : chs) {
			pipedWriter.write(ch);
			Thread.sleep(1000);
		}
		pipedWriter.close();
	}

	// Một Thread đọc dữ liệu xuất hiện trên 'pipedReader'.
	class ThreadRead extends Thread {
		@Override
		public void run() {
			try {
				int data = 0;
				while ((data = pipedReader.read()) != -1) {
					System.out.println((char) data);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				closeQuietly(pipedReader);
			}
		}
	}

	private void closeQuietly(Reader is) {
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
			}
		}
	}
}

Kết quả thực thi chương trình trên:


a
a
b
c
e

Tài liệu tham khảo:

  • https://www.javatpoint.com/java-io
  • https://docs.oracle.com/javase/tutorial/essential/io/index.html
  • http://o7planning.org/vi/10173/huong-dan-su-dung-luong-vao-ra-ky-tu-trong-java
4.9
09
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Java I/O Được gắn thẻ: IO

Hướng dẫn sử dụng luồng vào ra nhị phân trong Java
Thao tác với tập tin và thư mục trong Java

Có thể bạn muốn xem:

  • Giới thiệu luồng vào ra (I/O) trong Java (11/12/2017)
  • Hướng dẫn phân tích nội dung HTML sử dụng thư viện Jsoup (02/01/2018)
  • Hướng dẫn sử dụng Printing Service trong Java (17/12/2017)
  • Hướng dẫn sử dụng Lớp FilePermission trong java (16/12/2017)
  • Hướng dẫn sử dụng lớp Console trong java (15/12/2017)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (98059 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97699 lượt xem)
  • Giới thiệu Design Patterns (87764 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (86433 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83839 lượt xem)

Nội dung bài viết

  • 1 Đọc chuỗi từ console
  • 2 Sử dụng lớp FileReader và FileWriter
  • 3 Chuyển một luồng nhị phân thành luồng ký tự
  • 4 Sử dụng FilterInputStream và FilterOutputStream
  • 5 Sử dụng lớp BufferedReader và BufferedWriter
  • 6 Sử dụng lớp CharArrayReader và CharArrayWriter
  • 7 Ví dụ ghi một dữ liệu chung ra nhiều file
  • 8 Sử dụng lớp StringReader và StringWriter
  • 9 Ghi file với lớp PrintStream
  • 10 Ghi file với lớp PrintWriter
  • 11 Sử dụng lớp PushbackInputStream
  • 12 Sử dụng lớp PushbackReader
  • 13 Sử dụng lớp PipedReader và PipedWriter

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link