์ด์ „์— ์šฐ๋ฆฌ๋Š” IO API (Input/Output Application Programming Interface)์™€ java.io ํŒจํ‚ค์ง€์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค . ์ด ํŒจํ‚ค์ง€์˜ ํด๋ž˜์Šค๋Š” ์ฃผ๋กœ Java์—์„œ ์ŠคํŠธ๋ฆผ ์ž‘์—…์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ ์ŠคํŠธ๋ฆผ ์˜ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค .

์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” NIO API (New Input/Output) ๋ฅผ ๊ณ ๋ คํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค .

I/O์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ IO API๋Š” ์ŠคํŠธ๋ฆผ ์ง€ํ–ฅ์ ์ธ ๋ฐ˜๋ฉด NIO API๋Š” ๋ฒ„ํผ ์ง€ํ–ฅ์ ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ดํ•ดํ•ด์•ผ ํ•  ์ฃผ์š” ๊ฐœ๋…์€ ๋ฒ„ํผ ์™€ ์ฑ„๋„ ์ž…๋‹ˆ๋‹ค .

๋ฒ„ํผ๋Š” ๋ฌด์—‡์ด๋ฉฐ ์ฑ„๋„์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ฑ„๋„ ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๊ณ  ๋‚˜๊ฐ€๋Š” ๋…ผ๋ฆฌ์  ํฌํ„ธ์ธ ๋ฐ˜๋ฉด ๋ฒ„ํผ๋Š” ์ด ์ „์†ก๋œ ๋ฐ์ดํ„ฐ์˜ ์†Œ์Šค ๋˜๋Š” ๋Œ€์ƒ์ž…๋‹ˆ๋‹ค. ์ถœ๋ ฅํ•˜๋Š” ๋™์•ˆ ๋ณด๋‚ด๋ ค๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฒ„ํผ์— ๋„ฃ๊ณ  ๋ฒ„ํผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ„๋„๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅํ•˜๋Š” ๋™์•ˆ ์ฑ„๋„์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฒ„ํผ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•ด์„œ:

  • ๋ฒ„ํผ ๋Š” ๋‹จ์ˆœํžˆ ์ •๋ณด๋ฅผ ์“ฐ๊ณ  ์ •๋ณด๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์ž…๋‹ˆ๋‹ค.
  • ์ฑ„๋„ ์€ ํŒŒ์ผ์ด๋‚˜ ์†Œ์ผ“๊ณผ ๊ฐ™์€ I/O ์žฅ์น˜์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์ž…๋‹ˆ๋‹ค.

์ฑ„๋„์€ java.io ํŒจํ‚ค์ง€์˜ ์ŠคํŠธ๋ฆผ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋””๋กœ๋“  ๊ฐ€๋Š”(๋˜๋Š” ์–ด๋””์—์„œ ์˜ค๋Š”) ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋Š” ์ฑ„๋„ ๊ฐ์ฒด๋ฅผ ํ†ต๊ณผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ NIO ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด I/O ์—”ํ„ฐํ‹ฐ์— ๋Œ€ํ•œ ์ฑ„๋„๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฒ„ํผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฒ„ํผ๋กœ ์ž‘์—…ํ•˜์—ฌ ํ•„์š”์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

๋ฒ„ํผ์—์„œ ์•ž๋’ค๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ŠคํŠธ๋ฆผ์—์„œ ํ•  ์ˆ˜ ์—†๋Š” ๋ฒ„ํผ๋ฅผ "๊ฑท๊ธฐ"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋” ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋ฒ„ํผ๋Š” ์ถ”์ƒ Buffer ํด๋ž˜์Šค์™€ ์—ฌ๋Ÿฌ ํ•˜์œ„ ํ•ญ๋ชฉ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  • ๋ฐ”์ดํŠธ๋ฒ„ํผ
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • ๋ถ€๋™ ๋ฒ„ํผ
  • ๋”๋ธ”๋ฒ„ํผ
  • ๋กฑ๋ฒ„ํผ

ํ•˜์œ„ ํด๋ž˜์Šค ๊ฐ„์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ ๊ทธ๋“ค์ด ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ์œ ํ˜• โ€” bytes , ints , longs ๋ฐ ๊ธฐํƒ€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.

๋ฒ„ํผ ์†์„ฑ

๋ฒ„ํผ์—๋Š” ๋„ค ๊ฐ€์ง€ ์ฃผ์š” ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šฉ๋Ÿ‰, ํ•œ๊ณ„, ์œ„์น˜ ๋ฐ ํ‘œ์‹œ์ž…๋‹ˆ๋‹ค.

์šฉ๋Ÿ‰์€ ๋ฒ„ํผ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋ฐ์ดํ„ฐ/๋ฐ”์ดํŠธ ์–‘์ž…๋‹ˆ๋‹ค. ๋ฒ„ํผ์˜ ์šฉ๋Ÿ‰์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค . ๋ฒ„ํผ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด ๋” ์“ฐ๊ธฐ ์ „์— ์ง€์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์“ฐ๊ธฐ ๋ชจ๋“œ์—์„œ ๋ฒ„ํผ์˜ ํ•œ๊ณ„๋Š” ์šฉ๋Ÿ‰๊ณผ ๋™์ผํ•˜๋ฉฐ ๋ฒ„ํผ์— ์“ธ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋ฐ์ดํ„ฐ ์–‘์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ฝ๊ธฐ ๋ชจ๋“œ์—์„œ ๋ฒ„ํผ์˜ ํ•œ๊ณ„๋Š” ๋ฒ„ํผ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋ฐ์ดํ„ฐ ์–‘์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์œ„์น˜ ๋Š” ๋ฒ„ํผ์—์„œ ์ปค์„œ์˜ ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋ฒ„ํผ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ 0์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ฝ๊ฑฐ๋‚˜ ์“ธ ๋‹ค์Œ ์š”์†Œ์˜ ์ธ๋ฑ์Šค์ž…๋‹ˆ๋‹ค.

๋งˆํฌ ๋Š” ์ปค์„œ ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ฒ„ํผ๋ฅผ ์กฐ์ž‘ํ•  ๋•Œ ์ปค์„œ ์œ„์น˜๋Š” ๊ณ„์† ๋ณ€๊ฒฝ๋˜์ง€๋งŒ ํ•ญ์ƒ ์ด์ „์— ํ‘œ์‹œ๋œ ์œ„์น˜๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„ํผ ์ž‘์—… ๋ฐฉ๋ฒ•

์ด์ œ ์ฑ„๋„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ธฐ ์œ„ํ•ด ๋ฒ„ํผ(๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก)๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ฃผ์š” ๋ฉ”์„œ๋“œ ์ง‘ํ•ฉ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. allocate(int capacity) โ€” ์ด ๋ฉ”์„œ๋“œ๋Š” ์ง€์ •๋œ ์šฉ๋Ÿ‰์œผ๋กœ ์ƒˆ ๋ฒ„ํผ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ „๋‹ฌ๋œ ์šฉ๋Ÿ‰์ด ์Œ์˜ ์ •์ˆ˜์ธ ๊ฒฝ์šฐ allocate () ๋ฉ”์„œ๋“œ๋Š” IllegalArgumentException ์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค .

  2. capacity()๋Š” ํ˜„์žฌ ๋ฒ„ํผ์˜ ์šฉ๋Ÿ‰์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค .

  3. position()์€ ํ˜„์žฌ ์ปค์„œ ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ž‘์—…์€ ์ปค์„œ๋ฅผ ๋ฒ„ํผ์˜ ๋์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’์€ ํ•ญ์ƒ ์ œํ•œ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  4. limit()๋Š” ํ˜„์žฌ ๋ฒ„ํผ์˜ ํ•œ๊ณ„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  5. mark()๋Š” ํ˜„์žฌ ์ปค์„œ ์œ„์น˜๋ฅผ ํ‘œ์‹œ(์ €์žฅ)ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  6. reset()์€ ์ปค์„œ๋ฅผ ์ด์ „์— ํ‘œ์‹œ๋œ(์ €์žฅ๋œ) ์œ„์น˜๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.

  7. clear()๋Š” ์œ„์น˜๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์ œํ•œ์„ ์šฉ๋Ÿ‰์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ฒ„ํผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค . ์œ„์น˜, ํ•œ๊ณ„ ๋ฐ ๋งˆํฌ๋งŒ ๋‹ค์‹œ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

  8. flip()์€ ๋ฒ„ํผ๋ฅผ ์“ฐ๊ธฐ ๋ชจ๋“œ์—์„œ ์ฝ๊ธฐ ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•œ๊ณ„๋ฅผ ํ˜„์žฌ ์œ„์น˜๋กœ ์„ค์ •ํ•œ ๋‹ค์Œ ์œ„์น˜๋ฅผ ๋‹ค์‹œ 0์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  9. read() โ€” ์ฑ„๋„์˜ read ๋ฉ”์„œ๋“œ๋Š” ์ฑ„๋„์—์„œ ๋ฒ„ํผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ˜๋ฉด ๋ฒ„ํผ์˜ put() ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํผ์— ์“ฐ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  10. write() โ€” ์ฑ„๋„์˜ write ๋ฉ”์„œ๋“œ๋Š” ๋ฒ„ํผ์—์„œ ์ฑ„๋„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ˜๋ฉด ๋ฒ„ํผ์˜ get() ๋ฉ”์„œ๋“œ๋Š” ๋ฒ„ํผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  11. rewind()๋Š” ๋ฒ„ํผ๋ฅผ ๋˜๊ฐ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๋ฒ„ํผ๋ฅผ ๋‹ค์‹œ ์ฝ์–ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋ฉฐ ์œ„์น˜๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์ œํ•œ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ฑ„๋„์— ๋Œ€ํ•œ ๋ช‡ ๋งˆ๋””.

Java NIO์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ฑ„๋„ ๊ตฌํ˜„์€ ๋‹ค์Œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

  1. FileChannel โ€” ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ธฐ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค.

  2. DatagramChannel โ€” ์ด ํด๋ž˜์Šค๋Š” UDP(์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๊ทธ๋žจ ํ”„๋กœํ† ์ฝœ)๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์”๋‹ˆ๋‹ค.

  3. SocketChannel โ€” TCP(์ „์†ก ์ œ์–ด ํ”„๋กœํ† ์ฝœ)๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ธฐ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค.

  4. ServerSocketChannel โ€” ์›น ์„œ๋ฒ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ TCP ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ธฐ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ๊ฐ ์—ฐ๊ฒฐ์— ๋Œ€ํ•ด SocketChannel ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๊ด€ํ–‰

๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ์ž…๋‹ˆ๋‹ค. ๋จผ์ € ํŒŒ์ผ์„ ์ฝ๊ณ  ์ฝ˜์†”์— ๋‚ด์šฉ์„ ํ‘œ์‹œํ•œ ๋‹ค์Œ ํŒŒ์ผ์— ๋ฌธ์ž์—ด์„ ์”๋‹ˆ๋‹ค.

์ฝ”๋“œ์—๋Š” ๋งŽ์€ ์ฃผ์„์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.


// Create a RandomAccessFile object, passing in the file path
// and a string that says the file will be opened for reading and writing
try (RandomAccessFile randomAccessFile = new RandomAccessFile("text.txt", "rw");
    // Get an instance of the FileChannel class
    FileChannel channel = randomAccessFile.getChannel();
) {
// Our file is small, so we'll read it in one go   
// Create a buffer of the required size based on the size of our channel
   ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
   // Read data will be put into a StringBuilder
   StringBuilder builder = new StringBuilder();
   // Write data from the channel to the buffer
   channel.read(byteBuffer);
   // Switch the buffer from write mode to read mode
   byteBuffer.flip();
   // In a loop, write data from the buffer to the StringBuilder
   while (byteBuffer.hasRemaining()) {
       builder.append((char) byteBuffer.get());
   }
   // Display the contents of the StringBuilder on the console
   System.out.println(builder);
 
   // Now let's continue our program and write data from a string to the file
   // Create a string with arbitrary text
   String someText = "Hello, Amigo!!!!!";
   // Create a new buffer for writing,
   // but let the channel remain the same, because we're going to the same file
   // In other words, we can use one channel for both reading and writing to a file
   // Create a buffer specifically for our string โ€” convert the string into an array and get its length
   ByteBuffer byteBuffer2 = ByteBuffer.allocate(someText.getBytes().length);
   // Write our string to the buffer
   byteBuffer2.put(someText.getBytes());
   // Switch the buffer from write mode to read mode
   // so that the channel can read from the buffer and write our string to the file
   byteBuffer2.flip();
   // The channel reads the information from the buffer and writes it to our file
   channel.write(byteBuffer2);
} catch (FileNotFoundException e) {
   e.printStackTrace();
} catch (IOException e) {
   e.printStackTrace();
}

NIO API๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š” . ๋งˆ์Œ์— ๋“œ์‹ค ๊ฒ๋‹ˆ๋‹ค!