레이블이 java NIO인 게시물을 표시합니다. 모든 게시물 표시
레이블이 java NIO인 게시물을 표시합니다. 모든 게시물 표시

2019년 7월 3일 수요일

Java NIO 패키지를 사용한 CSV 파일 읽기


Java 코드를 사용해서 CSV 파일을 읽어 들이기 아주 단순한 예제 입니다.
코드 참고-실무에서 바로 통하는 자바

package project; 

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* CSV 파일 읽는 클래스
*/
public class ReadCSV {
    public static void main(String...args){
       //반환용 리스트 변수
        List> ret = new ArrayList>();
        //BufferedReader 생성
        BufferedReader br = null;
        
        try{
            // 대상 경로 설정
            br = Files.newBufferedReader(Paths.get("sample.csv"));
            Charset.forName("UTF-8");
            // CSV 파일에서 읽어 들인 1행분의 데이터
            String line = "";
            while((line = br.readLine()) != null){
                List tmpList = new ArrayList();
                String array[] = line.split(",");
                // 배열에서 리스트 Arrays
                tmpList = Arrays.asList(array);
                // 리스트 내용 출력
                System.out.println(tmpList);
                //반환용 리스트에 1행 데이터 저장
                ret.add(tmpList);
            }
            
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try{
                if(br != null)    br.close();
            }catch(IOException e){
                e.printStackTrace();
            }
            
        }
    }
}

2016년 7월 22일 금요일

JDK 1.4 튜토리얼 - 2장 NIO- 논블록킹-Polling

2.3 넌블록킹 I/O

JDK1.4 이전에는 java.io에서는 non-blocking(상세) 을 지원하지 않음
특징
  • 작업 종료 후 응답이 돌아오기 전에 다음 작업 수행할 수 있음
  • 많은 수의 I/O 커넥션을 관리시 오버헤드를 감소 시킴(**)
  • C/S 서버 환경에서 좋은 성능을 발휘 함
  • Non-Blocking 기법은
    • Polling 방식 - 주기적으로 확인
    • Multiplexing 방식 - select를 사용하는 event 방식
다중 쓰레드를 사용함(Blocking 방식)
  • 단점
    • 많은 쓰레드 자원을 소비 한다.
  • 장점
    • 구조를 단순화 할 수 있음
  • 만약 다중 쓰레드를 단일 쓰레드 방식으로 변경하면 특정 통신에 이상 발생하면 나머지 모든 멈추는 현상이 발생 하게 된다.
Polling(폴링)
  • 단점
    • 폴링 대기시간이 존재하면 결국 대기 시간을 줄이게 되면 부하가 상승함.
    • 매우 짧고 높은 응답 성능을 요구하는 서버에서는 사용이 적절하지 않음

package ns.jdk14;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.*;

public class PollingChatServer implements Runnable{
   private static final int sleepTime = 100; //SLEEP_TIME
   private int port;   //포트번호
   private Vector<Socket> sockets = new Vector<>();
   private Set<Socket> closedSockets = new HashSet<>();

   public PollingChatServer(int port) {
       this.port = port;
       Thread t = new Thread(this,"PollingChatServer");
       t.start();
   }

   @Override
   public void run() {
       try{
           //1) 논블록킹 서버 소켓 OPEN
           ServerSocketChannel ssc = ServerSocketChannel.open();
           ssc.configureBlocking(false);
           ServerSocket ss = ssc.socket();
           InetSocketAddress isa = new InetSocketAddress(port);
           ss.bind(isa);

           ByteBuffer buffer = ByteBuffer.allocate(4096);
           System.out.println("Listening on port "+port);
           while(true){
               //2) 서버 소켓에 새로운 연결이 들어옴
               SocketChannel sc = ssc.accept();
               //연결이 있는 경우에는 not null 이고 null 이면 없는 경우 이다.
               if(sc != null){
                   Socket newSocket = sc.socket();
                   System.out.println("Connection from "+newSocket);
                   //논블록킹으로 설정    
                   newSocket.getChannel().configureBlocking(false);
                   sockets.addElement(newSocket);
               }
               //3) 클라이언트 소켓중의 하나로 데이터가 읽혀짐
               for(Enumeration<Socket> e = sockets.elements();
                   e.hasMoreElements();){
                   Socket socket = null;
                   try{
                       socket = e.nextElement();
                       SocketChannel sch = socket.getChannel();
                       buffer.clear();
                       sch.read(buffer);
                       //Data가 있는 경우
                       if(buffer.position() > 0){
                           buffer.flip();
                           System.out.println("Read "+buffer.limit()
                                   +" bytes from "+sch.socket());
                           sendTOAll(buffer);
                       }

                   }catch(IOException ie){
                       closedSockets.add(socket);
                   }
               }

               removeClosedSockets();
               try {
                   Thread.sleep(sleepTime);
               }catch(InterruptedException ie){}
           }
       }catch(IOException e){e.printStackTrace();}
   }
   /**
    * 4) Data 클라이언트 소켓에
    * @param bb
    */
   private void sendTOAll(ByteBuffer bb){
       for(Enumeration<Socket> e = sockets.elements();
           e.hasMoreElements();){
           Socket socket = null;

           try{
               socket = e.nextElement();
               SocketChannel sc = socket.getChannel();
               //버퍼의 포지션을 시작 위치로 변경함.
               bb.rewind();
               //보낼것이 있는 경우
               while(bb.remaining() > 0){
                   sc.write(bb);
               }
           }catch(IOException ie){
               closedSockets.add(socket);
           }
       }
   }
   /**
    * 5) 연결 종료된 소켓 제거
    */
   private void removeClosedSockets(){
       for(Iterator<Socket> it=closedSockets.iterator();it.hasNext();){
           Socket socket = it.next();
           sockets.remove(socket);
           System.out.println("Removed "+socket);
       }
       closedSockets.clear();
   }
   public static void main(String[] args) {
       //Integer.parseInt(args[0]);
       int port = 5555;
       new PollingChatServer(port);
   }
}

출처 : 인포북 JDK 1.4 Tutorial