퉁탕퉁탕 만들어보자

InputStream 본문

Computer/Java

InputStream

호숀티 2022. 5. 7. 01:28
반응형

네트워크나, 파일 입출력을 하게될때 InputStream이나 OutputStream을 사용하게된다.

 

네크워크에서 String을 읽어오는 예제를 보자

    HttpURLConnection connection = openConnection(src);
    if (!isValidResponse(connection)) {
        Log.e(TAG, "Connection error : " + connection.getResponseCode());
        connection.disconnect();
        return null;
    }
    try (InputStream inputStream = connection.getInputStream()) {
        List<String> mImageSrcList = new LinkedList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))){
            String line;
            while ((line = reader.readLine()) != null) {
                mImageSrcList.add(line);
            }
            return mImageSrcList;
        } catch (IOException e) {
            Log.e(TAG, "IOException occurred during image tag's data source " + e.toString());
        }
        return null;
    } finally {
        connection.disconnect();
    }

커넥션을 열고 connection.getInputStream으로 inputStream을 가져온다.

그리고 BufferedReader와 InputStream를 가지고 inputStream을 readLine()으로 한 line씩 읽어서 List<String>에 더하고 있다.

 

* inputStream객체만 얻어오고 read() 하기 전에 connection을 disconnect()하게 되면 어떻게 될까?

socket closed 익셉션이 나며 제대로 읽어올 수가 없다.

inputStream은 실제로 메모리가 전부 할당되어있고 거기에 데이터가 들어있는 방식이 아니다.

read하면서 하나씩 읽어온다.

 

1. InputStreamReader

public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

InputStreamReader는 byte로 이루어진 stream => character의 stream으로 바꾸어주는 다리이다.

byte들을 읽어서 character로 디코드를 해준다. 

    public int read() throws IOException {
        return sd.read();
    }

이렇게 하면 딱 한글자를 read하고, 

    public int read(char cbuf[], int offset, int length) throws IOException {
        return sd.read(cbuf, offset, length);
    }

이렇게 하면 offset부터 length개를 읽어서 cbuf에 저장한다.

 

2.  BufferdReader

우리가 보통 char의 배열을 사용하기보다는 String을 쓰기 때문에 BufferedReader를 사용하게 되는데, BufferedReader는 character-input stream으로 buffering을 통해서 character나, array나 line을 효율적으로 읽어온다.

 

BufferedReader는 생성자 argument로 Reader를 받는다.

따라서 inputStream을 직접 넣을 수 없고, inputStream의 reader를 생성해서 넣어줘야한다.

Buffer의 사이즈는 생성할때 정할수 있고, 정하지 않으면 default size로 사용하는데, 8192이다.

    public BufferedReader(Reader in) {
        this(in, defaultCharBufferSize);
    }

 

위의 예제와 같이 readLine()을 많이 사용하게되는데, line terminator을 만날때까지 딱 읽어서 String을 만들어서 return해주는 매우 편리한 친구이다. line terminator로는 '\n', '\r'이 사용된다.

public String readLine() throws IOException

 

stream을 핸들하면서 몇가지 놓치면 안되는점은, 

첫째, inputStream은 한번 읽으면 다시 읽을 수 없다! connection을 다시 열고, getInputStream을 한뒤에 새로 읽어야한다.

둘째, 항상 잘 close해줘야한다. stream자체가 socket이나, file에대한 참조 리소스를 갖고있기 때문에 close를 해줘야 제대로 collection이 될 수 있다.

728x90
반응형

'Computer > Java' 카테고리의 다른 글

HashMap 충돌 (java 8)  (0) 2022.05.08
OutputStream  (0) 2022.05.07
Java의 primitive type, reference type, wrapper class  (0) 2022.04.17
Math class - Java  (0) 2022.04.03
String 함수들, 자료구조 - Java  (0) 2022.04.03