ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA I/O
    Java 2020. 2. 6. 09:01
    반응형

    I/O

    Input Output의 약자. 입출력을 통칭하는 용어

    JAVA I/O

    JVM 기준으로 읽을 때는 Input, 파일로 쓰거나 외부로 전송시에는 Output

    초기 단계의 JAVA I/O

    java.io Package만 제공 - Byte 기반의 데이터를 처리하기 위해서 여러 종류의 Stream이라는 Class를 제공

    Java에서의 Stream : 끊기지 않고 연속적인 데이터

    InputStream & OutputStream Class : 읽는 작업 & 쓰는 작업, byte

    Reader & Writer Class : 읽기 & 쓰기, char 기반의 문자열로만 되어있는 파일

    JDK 1.4 ~

    NIO(New I/O) 추가 - Buffer와 Channel 기반으로 데이터 처리

    JDK 7 ~

    NIO2 추가 - 파일을 보다 효율적으로 처리, 기존에 있는 여러 단점 보완

    Java의 File & Files Class 차이점

    java.io.File Class

    파일 뿐만 아니라, 파일의 디렉터리(path) 정보도 포함

    정체가 불분명하거나, 심볼릭 링크와 같은 유닉스 계열의 파일에서 사용하는 몇몇 기능을 제공하지 못함

    객체를 생성하여 데이터를 처리

    java.nio.file.Files Class (JDK 7 ~) 

    java.io.File Class에 있는 메서드들을 대체하여 제공

    모든 메서드가 static으로 선언되어 있기 때문에 별도의 객체를 생성할 필요가 없음

    File Class의 기능

    생성한 파일 객체가 가리키고 있는 것을 확인하는 기능

    • 존재여부, 파일/디렉터리 구분, 읽기/쓰기/실행 가능여부, 수정일자 확인

    해당 파일을 조작하는 기능

    • 이름 변경, 삭제, 생성, 전체 디렉터리 확인

    해당 디렉터리를 조작하는 기능

    • 파일 목록 가져오기, 생성, 삭제

    File Class의 생성자

    // child - 디렉터리도 받을 수 있고, 파일 이름도 받을 수 있음
    
    // 이미 생성되어 있는 File 객체(parent)와 그 디렉터리의 하위 디렉터리 이름으로 새로운 File 객체 생성
    File(File parent, String child)
    
    // 지정한 pathname(디렉터리 or 디렉터리+파일) 이름으로 File 객체 생성
    File(String pathname)
    
    // 상위 디렉터리(parent)와 하위 디렉터리(child)로 File 객체 생성
    File(String parent, String child)
    
    // URI(Uniform Resource Identifier)에 따른 File 객체 생성 - java.net.URI 클래스 참고
    File(URI uri)

    File Class를 이용하여 파일의 디렉터리와 상태 확인

    File Class의 separator static 변수

    // 운영체제마다 다른 디렉터리 구분 기호를 변수로 통일한 것
    String pathName = File.separator + "jamie" + File.separator + "text";
    
    /* 윈도우
     * \는 escape문자로 사용하려면 \\ 이렇게 써야함
     */
    String pathName = "C:\\jamie\\text";
    
    /* 유닉스
     * /로 디렉터리 구분"
     */
    String pathName = "/jamie/text";

     

    메서드들

    // 파일 또는 디렉터리가 존재하면 true
    boolean extists()
    
    // 디렉터리 생성 - 성공시 true
    boolean mkdir()
    
    // 디렉터리들 생성 (리눅스의 mkdir -p) - 성공시 true
    boolean mkdirs()
    
    // 디렉터리가 맞으면 true
    boolean isDirectory()
    
    // 파일이 맞으면 true
    boolean isFile()
    
    // 숨겨진 파일이 맞으면 true
    boolean isHidden()
    
    // 읽기권한이 있으면 true
    boolean canRead()
    
    // 쓰기권한이 있으면 true
    boolean canWrite()
    
    // 실행권한이 있으면 true - JDK6 ~
    boolean canExecute()
    
    /* 생성일자 확인 - long으로 리턴해주므로 Date 클래스를 이용하여 시간 확인할 것
     * 예) new Date(file.lastModified())
     */
    long lastModified()
    
    // 파일 혹은 디렉터리 삭제 - 성공시 true
    boolean delete()

    File Class를 이용하여 파일 처리

    생성 메서드

    /* 비어있는 새로운 파일 생성 - 성공시 true
     * IOException을 발생시키므로 try-catch로 묶어주기
     * java.io.IOException import해야 함
     */
    boolean createNewFile()
    // 예제
    try {
        file.createNewFile();
    } catch (IOExcetion ioe) {
        ioe.printStackTrace();
    }

    조회 메서드

    // 상대경로
    String getAbsolutePath()
    File getAbsoluteFile()
    
    // 절대경로
    String getCanonicalPath()
    File getCanonicalFile()
    
    // 파일명 or 디렉터리는 전체 디렉터리
    String getName()
    
    // 드라이브를 제외한 디렉터리 + 파일명
    getPath()
    
    // 파일 이름을 제외한 디렉터리만 출력
    getParent()

    File Class의 list 메서드들 - 디렉터리에 있는 목록을 살펴보기 위함

    list로 시작하는 File 클래스에 있는 메서드 (6개)

    /* JVM이 수행되는 OS에서 사용중인 파일 시스템의 root 디렉터리 목록을 File 배열로 리턴
     * static 메서드이므로 File 객체를 별도로 생성할 필요는 없음
     */
    static File[] listRoots()
    
    // 현재 디렉터리의 하위 목록을 String 배열로 리턴
    String[] list()
    
    // 현재 디렉터리의 하위에 있는 목록 중, 매개 변수로 넘어온 filter의 조건에 맞는 목록을 String 배열로 리턴
    String[] list(FilenameFilter filter)
    
    // 현재 디렉터리의 하위에 있는 목록을 File 배열로 리턴
    File[] listFiles()
    
    // 현재 디렉터리의 하위에 있는 목록 중, 매개 변수로 넘어온 filter의 조건에 맞는 목록을 File 배열로 리턴
    File[] listFiles(FileFilter filter)
    
    // 현재 디렉터리의 하위에 있는 목록 중, 매개 변수로 넘어온 filter의 조건에 맞는 목록을 File 배열로 리턴
    File[] listFiles(FilenameFilter fileter)

    FileFilter 인터페이스에 선언된 메서드

    // 매개 변수로 넘어온 File 객체가 조건에 맞는지 확인
    boolean accept(File pathname)

    FilenameFilter 인터페이스에 선언된 메서드

    // 매개 변수로 넘어온 디렉터리(dir)에 있는 디렉터리나 파일 이름(name)이 조건에 맞는지 확인
    boolean accept(File dir, String name)

    JDK 7 ~ 버전 사용시 File 클래스보다 java.nio.file.Files 클래스를 사용할 것

    InputStream & OutputStream (abstract) Class

    Java Stream의 부모들

    기본적으로 Java I/O는 InputStream과 OutputStream이라는 abstract Class를 통해 제공

    byte를 다루기 위한 것

    데이터를 읽을 때 : InputStream의 자식 Class를 통하여 읽기

    데이터를 쓸 때 : OutputStream의 자식 Class를 통하여 쓰기

    InputStream Class

    선언

    public abstract class InputStream extends Object implements Closeable
    
    /* Closeable - close() 라는 메서드만 선언된 인터페이스
     * 어떤 리소스를 열었던 간 해당 인터페이스를 구현하면 close() 메서드를 이용해 닫으라는 의미
     * 해당 리소스(Stream을 통해 작업할 수 있는 모든 것, 파일, 네트워크 연결 등)를 다른 클래스에서도 작업할 수 있도록
     * java.io Package에 있는 Class를 사용할 때는 하던 작업이 종료되면 close() 메서드로 닫아줄 것
     */ 

    메서드

    // Stream에서 중단 없이 읽을 수 있는 Byte의 개수를 리턴
    int available()
    
    /* Stream의 현재 위치를 표시(mark)
     * 매개 변수로 넘긴 int값은 표시해둔 자리의 최대 유효 길이
     * 그 값을 넘어가면, 표시해 둔 자리는 더이상 의미가 없어짐
     */
    void mark(int readlimit)
    
    // 현재 위치를 mark() 메서드가 호출되었던 위치로 되돌림
    void reset()
    
    // mark나 reset() 메서드가 수행 가능한지를 확인
    boolean markSupported()
    
    // Stream에서 다음 Byte를 읽음. 유일한 abstract 메서드
    abstract int read()
    
    // 매개 변수로 넘어온 Byte 배열에 데이터를 담음. 리턴 값은 데이터를 담은 개수
    int read(byte b)
    
    /* 매개 변수로 넘어온 Byte 배열에 데이터를 담음. 리턴 값은 데이터를 담은 개수
     * 단, 특정 위치(off)부터 지정한 길이(len)만큼의 데이터
     */
    int read(byte[] b, int off, int len)
    
    // 매개 변수로부터 넘어온 길이(n)만큼의 데이터를 건너 뜀
    long skip(long n)
    
    /* Stream에서 작업중인 대상 해제
     * 수행한 후에는 다른 메서드를 사용하여 데이터 처리 불가
     *
     * Stream을 다룰 때 close() 메서드를 호출하지 않으면, 예상치도 못한 심각한 오류 발생
     */
    close()

    InputStream을 확장한 주요 Class

    • AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream(org.omg.CORBA.portable.InputStream), ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

    주요 Class 중 주로 많이 사용하는 Stream

    /* 파일을 읽을 때 사용
     * 주로 이미지와 같이 Byte Code로 된 데이터를 읽을 떄 사용
     *
     * FileInputStream을 확장한 Class
     * BufferedInputStream, CheckedInputStream, CipherInputStream, DataInputStream,
     * DeflaterInputStream, DigestInputStream, InflaterInputStream, LineNumberInputStream,
     * ProgressMonitorInputStream, PushbackInputStream
     */
    FileInputStream
    
    // 다른 입력 스트림을 포괄하며, 단순히 InputStream Class가 Override되어 있음
    FilterInputStream
    
    // ObjectOutputStream으로 지정된 데이터를 읽는 데 사용
    ObjectInputStream

    OutputStream Class 

    선언

    public abstract class OutputStream extends Object implements Closeable, Flushable
    
    /* Flushable 인터페이스 - flush() 메서드 하나만 선언되어 있음
     * buffer를 가지고 데이터를 쌓아두다가, flush() 메서드를 이용하여 buffer를 사용
     */

    InputStream처럼 close()를 꼭 호출해서 열었던 리소스를 닫아야만 문제가 생기지 않음

    메서드는 InputStream의 클래스들 이름을 InputStream 대신 OutputStream을 붙여주면 됨

    Reader & Writer (abstract) Class

    char 기반의 문자열을 처리하기 위한 클래스

    - 일반적인 text editor로 볼 수 있는 파일들을 처리하기 위한 클래스

    Reader Class

    선언

    public abstract class Reader extends Object implements Readable, Closeable

    메서드 - InputStream 메서드와 중복이 많음

    // Reader에서 작업할 대상이 읽을 준비가 되어있는지 확인
    boolean ready()
    
    /* Reader 현재 위치를 표시(mark)
     * 매개 변수로 넘은 int값은 표시해 둔 자리의 최대 유효 길이
     * 이 값을 넘어가면 표시해 둔 자리는 의미가 없어짐
     */
    void mark(int eradAheadLimit)
    
    // 현재 위치를 mark() 메서드가 호출되었던 위치로 되돌림
    void reset()
    
    // mark()나 reset() 메서드가 수행 가능한지를 확인
    boolean markSupported()
    
    // 하나의 char를 읽음
    int read()
    
    // 매개 변수로 넘어온 char 배열에 데이터를 담음, 리턴값 = 데이터를 담은 개수
    int read(char[] cbuf)
    
    /* 매개 변수로 넘어온 char 배열에 특정 위치(off)부터 지정한 길이(len)만큼의 데이터를 담음
     * 리턴값 = 데이터를 담은 개수
     */
    abstract int read(char[] cbuf, int off, int len)
     
    // 매개 변수로 넘어온 CharBuffer 클래스의 객체에 데이터를 담음, 리턴값 = 데이터를 담은 갯수
    int read(CharBuffer target)
    
    // 매개 변수로 넘어온 개수만큼의 char를 건너뜀
    long skip(long n)
    
    /* Reader에서 작업중인 대상을 해제, 해당 메서드 수행 후에는 다른 메서드를 사용하여 데이터 처리 불가
     * 모든 작업이 끝난 이후 호출해야 함
     */ 
    abstract void close()

    Reader를 확장한 주요 클래스

    // 자주 쓰이는 것 - BufferedReader, InputStreamReader
    BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

    Writer Class 

    선언

    public abstract class Writer extends Object implements Appendable, Closeable, Flushable
    
    // Appendable - JDK 5 ~ 각종 문자열을 추가하기 위해서 선언

    메서드 - OutputStream 클래스에 선언된 메서드와 대부분 동일, append() 메서드가 존재하는 것은 다름

    /* Writer 클래스(JDK 1.1~) - 데이터를 저장하기 위한 메서드가 write()밖에 없었음
     * append()와 write() 메서드는 비슷함
     * 단, StringBuilder나 StringBuffer로 문자열을 만들면 append() 메서드가 훨씬 편함
     */
    
    // 매개 변수로 넘어온 char를 추가
    writer append(char c)
    
    /* 매개 변수로 넘어온 CharSequence를 추가
     * CharSequence - 인터페이스, String / StringBuilder / StringBuffer가 해당 인터페이스를 구현한 대표 클래스
     */
    writer append(CharSequence csq)
    
    // 매개 변수로 넘어온 CharSequence를 추가, 해당 문자열의 시작 위치(start)와 끝 위치(end)를 지정
    writer append(CharSequence csq, int start, int end)
    
    // 매개 변수로 넘어온 char의 배열을 추가
    void writer(char[] cbuf)
    
    // 매개 변수로 넘어온 char의 배열을 특정 위치(off)부터 특정 길이(len)만큼 추가
    abstract void write(char[] cbuf, int off, int len)
    
    // 매개 변수로 넘어온 int 값에 해당하는 char를 추가
    void write(int c)
    
    // 매개 변수로 넘어온 문자열을 씀
    void write(String str)
    
    // 매개 변수로 넘어온 문자열을 추가, 해당 문자열의 시작 위치(start)와 끝 위치(end)를 지정
    void write(String str, int off, int len)
    
    // 버퍼에 있는 데이터를 강제로 대상 리소스에 쓰도록 함
    abstract void flush()
    
    // 쓰기 위해 연 스트림 해제
    abstract void close()

    FileWriter & BufferedWriter Class

    FileWriter

    char 기반의 내용을 파일로 쓰기 위해 사용

    생성자

    // File 객체를 매개 변수로 받아 객체 생성
    FileWriter(File file)
    
    /* File 객체를 매개 변수로 받아 객체 생성
     * append 값을 통하여 해당 파일의 뒤에 붙일지 (append=true)
     * 해당 파일을 덮어 쓸지(append=false)를 정함
     */
    FileWriter(File file, boolean append)
    
    // FileDscriptor 객체를 매개 변수로 받아 객체를 생성
    FileWriter(FileDescriptor fd)
    
    // 지정한 문자열의 디렉터리와 파일 이름에 해당하는 객체를 생성
    FileWriter(String fileName)
    
    // 지정한 문자열의 디렉터리와 파일 이름에 해당하는 객체를 생성, append 값에 따라 데이터를 추가할지 덮어쓸지 지정
    FileWriter(String fileName, boolean append)

    생성시 IOException이 발생할 수 있음. 일반적으론 아래의 상황에서 발생

    • 매개 변수로 넘어온 파일 이름이 파일이 아닌 경로를 의미한 경우

    • 해당 파일이 존재하지는 않지만, 권한 등의 이유로 생성할 수 없는 경우

    • 파일이 존재하지만, 여러 이유로 파일을 열 수 없는 경우

    BufferedWriter

    FileWriter의 write()나 append() 메서드를 사용하여 데이터를 쓰면, 메서드를 호출했을 때 파일에 쓰기 때문에 매우 비효율적, 해당 단점을 보완하기 위해 BufferedWriter 클래스가 있음

    생성자

    // Writer 객체를 매개 변수로 받아 객체를 생성
    BufferedWriter(Writer out)
    
    // Writer 객체를 매개 변수로 받아 객체를 생성, 두 번째 매개변수에 있는 size로 버퍼 크기 지정
    BufferedWriter(Writer out, int size)

    버퍼라는 공간에 저장할 데이터를 보관해 두었다가, 버퍼가 차게되면 데이터를 저장하도록 도와줌

    매우 효율적인 저장이 가능함

    매개 변수로 writer를 받듯, FileWriter를 사용하면 파일에 저장할 수 있게 됨

    유의 사항

    FileWriter나 BufferedWriter 변수를 try문 안에서 선언했다면, finally에서 close() 메서드를 호출할 수 없음

    • 변수들을 try 이후에 나오는 중괄호에서 선언하면 catch나 finally, 그리고 try-catch 문장 밖에서 참조하려 할 때 컴파일 에러 발생

    • 즉, finally에서 close()하려면 반드시 try 문장 전 변수 선언해야 함

    finally에서 close()를 하는 이유

    • try 블럭의 끝 부분에서 close() 메서드를 구현했다면, 중간에 예외 발생시 close() 메서드가 호출되지 않고, 이를 피하려면 catch 블럭에서 일일이 close()를 모두 구현해주어야 함

    가장 마지막에 연 객체부터 닫아주어야 정상적인 처리가 가능함

    • 예) FileWriter, BufferedWriter 순으로 객체를 생성했다면, 반대인 BufferedWriter, FileWriter 순으로 닫아주어야 함

    FileReader & BufferedReader Class 

    FileReader & BufferedReader

    FileWriter & BufferedWriter 클래스의 메서드에서 Writer를 Reader로 변경해주면 대부분의 코드가 쉽게 작성됨

    데이터를 읽는 코드 예

    String data;
    while((data=bufferedReader.readLine()) != null) {
        System.out.println(data);
    }

    Scanner Class

    java.util.Scanner, 사용하려면 import 해주어야 함

    텍스트 기반의 기본 자료형이나 문자열 데이터를 처리하기 위한 클래스

    정규 표현식(Regular Expression)을 사용하여 데이터를 잘라 처리할 수도 있음

    생성자는 종류가 다양함

    hasNextLine() : 다음 줄이 있는지 확인하는 메서드

    nextLine() : 다음 줄의 내용을 문자열로 한 줄씩 리턴

    반응형

    'Java' 카테고리의 다른 글

    Serializable  (0) 2020.02.07
    Java NIO  (0) 2020.02.06
    Thread 관련 - Object, ThreadGroup, ThreadLocal, volatile  (0) 2020.01.16
    Thread Class  (0) 2020.01.15
    Thread 개념 및 Runnable Interface VS Thread Class  (0) 2020.01.13

    댓글

Designed by Tistory.