카테고리 없음

[TIL] 2022년 10월 1일 토요일

2022. 10. 1. 11:28

6.2 표준입출력의 대상변경

- System.in, System.out, System.err의 입출력 대상은 콘솔화면 → setIn(), setOut(), setErr()를 사용하여 다른 입출력 대상으로 변경 가능 → JDK1.5부터 Scanner클래스를 제공하여 System.in으로 데이터를 입력받는 것이 편리해짐

더보기
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class StandardIOEx {
    public static void main(String[] args) {
        PrintStream ps = null;
        FileOutputStream fos =null;

        try {
            fos = new FileOutputStream("test.txt");
            ps = new PrintStream(fos);
            System.setOut(ps);
        }catch (IOException e){
            System.err.println("File not found");
        }
        System.out.println("Hello by System.out");
        System.err.println("Hello by System.err");
    }
}
//자바의 정석 교재 예제
C:\jdk1.8\work\ch15>java StandardIOEx3
Hello by System.err

C:\jdk1.8\work\ch15>type test.txt
Hello by System.out

C:\jdk1.8\work\ch15>

//내 컴퓨터로 실행
Macui-iMac:src mac$ java StandardIOEx.java
Hello by System.err
Macui-iMac:src mac$ type test.txt
-bash: type: test.txt: not found
Macui-iMac:src mac$ cat test.txt
Hello by System.out
Macui-iMac:src mac$

- 내 컴퓨터로 예제를 실행했으나 type test.txt가 작동하지 않음 → terminal이라서 type 대신 cat으로 변경

Macui-iMac:src mac$ java StandardIOEx >> output.txt
Hello by System.err
Macui-iMac:src mac$ cat output.txt
Macui-iMac:src mac$ cat output.txt
Macui-iMac:src mac$ java StandardIOEx < output.txt
Hello by System.err
Macui-iMac:src mac$ cat output.txt
Macui-iMac:src mac$

- output.txt로 데이터를 받아 새로운 내용을 저장하는 것 같은데 terminal에서는 output.txt파일이 생성되기만하고 내용을 입력하지 못함 → 다른 방법을 찾아봐야 함

 

 

6.3 RandomAccessFile

 

- RandomAccessFile 클래스는 DataOutput 인터페이스와 DataInput 인터페이스를 구현 → random access file에 대하여 읽고 쓰는 것 모두 지원하는 클래스

- 파일 포인터를 사용하여 파일의 어느 위치에서나 읽고 쓰기가 가능함.

- 파일 포인터는 파일의 첫 부분에 위치. 파일을 읽고 쓸 때 순차적으로 읽고 쓴다면 별도의 작업이 필요 없고, 원하는 임의의 위치가 있다면 파일 포인터를 원하는 위치로 이동한 다음 작업함.

- 모든 입출력 클래스가 파일 포인터를 갖고있으나 RandomAccessFile처럼 사용자가 포인터의 위치를 변경할 수 없음

생성자 설명
RandomAccessFile(File file, String mode) 매개변수 파일을 읽거나 읽고 쓸 RandomAccessFile 스트림 인스턴스를 생성
RandomAccessFile(String name, String mode) 매개변수 이름의 파일을 읽거나 읽고 쓸 RandomAccessFile 스트림 인스턴스를 생성
* mode의 값
r     : 파일로부터 읽기만을 수행할 때
rw  : 파일에 읽기와 쓰기. 지정된 파일이 없으면 새로운 파일 생성
rws: rw와 동일하나 출력내용이 파일에 지연 없이 바로 쓰이게 함. rwd는 파일의 내용만, rws는 파일의 메타정보 포함
자료형 메소드 설명
FileChannel getChannel() Returns the unique FileChannel object associated with this file.
파일과 연관된 고유한 FileChannel 객체를 반환
FileDescriptor getFD() Returns the opaque file descriptor object associated with this stream.
이 스트림과 연관된 불분명한 파일 디스크립터 객체를 반환
long getFilePointer() Returns the current offset in this file.
이 파일의 현재 offset을 반환. 'ABCD'가 저장된 파일에서 파일 포인터가 현재 'C'에 있다면 시작점인 'A'와 차이가 2이므로 2를 반환
long length() Returns the length of this file.
파일의 길이를 반환
void seek(long pos) Sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs.
이 파일의 시작점에서 다음으로 읽거나 쓸 오프셋을 설정. 'ABCD'가 저장된 파일에서 seek(2)를 선언한다면 시작점인 A에서 2가 떨어진 'C'부터 읽고 씀
void setLength(long newLength) Sets the length of this file.
파일의 길이를 설정
int  skipBytes(int n) Attempts to skip over n bytes of input discarding the skipped bytes.
지정된 수만큼 byte를 건너뛰고 건너뛴 바이트는 버림

 

더보기
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileEx {
    public static void main(String[] args) {
        int[] score = { 1, 100, 90, 90,
                2, 70, 90, 100,
                3, 100, 100, 100,
                4, 70, 60, 80,
                5, 70, 90, 100
        };

        try {
            RandomAccessFile raf = new RandomAccessFile("score2.dat", "rw");
            for(int i=0; i<score.length; i++){
                //raf.write(score[i]);
                raf.writeInt(score[i]);
            }

            while (true){
                System.out.println(raf.readInt());
            }
        }catch (EOFException eof){
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileEx2 {
    public static void main(String[] args) {
        int sum = 0;

        try {
            RandomAccessFile raf = new RandomAccessFile("score2.dat", "r");
            int i=4;

            while (true){
                raf.seek(i);
                sum += raf.readInt();
                i += 16;
            }
        }catch (EOFException eof){
            System.out.println("sum = " + sum);
        }catch (IOException ioe){
            ioe.printStackTrace();
        }
    }
}

- 더보기 속 예제를 푸는데 답이 sum = 38165092라고 나왔다. 환장할 노릇이었지만 내 실수인 걸 발견했다. readInt()인데 read()를 넣었다. read()는 바이트로 읽으니 주의하자.

더보기
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileEx2 {
    public static void main(String[] args) {
        int sum = 0;

        try {
            RandomAccessFile raf = new RandomAccessFile("score2.dat", "r");
            int i=4;

            while (true){
                raf.seek(i);
                System.out.println(raf.readInt());
                sum += raf.readInt();
                i += 16;
            }
        }catch (EOFException eof){
            System.out.println("sum = " + sum);
        }catch (IOException ioe){
            ioe.printStackTrace();
        }
    }
}

- 국어점수만 잘 읽어오는지 궁금해서 readInt()한 다음 sum에 더하게 해봤는데 결과값이 410에서 430으로 바뀌었다. readInt()를 한다음 또 readInt()를 해서 파일 포인터가 다음 과목값을 더해 계산한 것이다. 출력해보고싶을 땐 새로운 변수를 선언해 그 변수에 readInt()한 값을 넣고, 출력하고 더해야 값이 변하지 않을 것이다.

 

 

6.4 File

- File 클래스는 파일과 디렉터리 모두 다룰 수 있어 File 인스턴스는 파일을 가리킬수도, 디렉터리를 가리킬 수 도 있음

타입 필드 설명
static String pathSeparator The system-dependent path-separator character, represented as a string for convenience.
운영체제 의존적인 경로 구분 문자열
static char pathSeparatorChar The system-dependent path-separator character.
운영체제 의존적인 경로 구분 문자
static String separator The system-dependent default name-separator character, represented as a string for convenience.
운영체제 의존적인 기본 이름 구분 문자열
static char separatorChar The system-dependent default name-separator character.
운영체제 의존적인 기본 이름 구분 문자

- 운영체제 의존적인은 직역하다보니 나온 표현인데 Java 파일이 실행되는 운영체제에서 사용중인으로 생각하는게 좋다.

생성자 설명
File(File parent, String child) 부모 추상경로명에 있는 파일과 자식 경로명으로부터 child이름의 새로운 File 인스턴스를 생성
File(String pathname) 매개변수로 받은 경로명을 추상경로명으로 변환하여 새로운 File 인스턴스를 생성
File(String parent, String child) 부모 경로명과 자식 경로병으로부터 새로운 File 인스턴스를 생성
File(URI uri) URI를 추상경로명으로 바꿔 주어진 파일로 새로운 File인스턴스를 생성
타입 메소드 설명
String getName() 추상경로명이 나타내는 파일이나 디렉터리의 이름을 반환
String getPath() 추상경로명을 String 타입의 경로명으로 변환하여 반환
String
File
getAbsolutePath()
getAbsoluteFile()
추상경로명을 String 타입의 절대경로로 반환
추상경로명을 File 타입의 절대경로로 반환
String
File
getParent()
getParentFile()
파일의 상위 추상경로명을 String 타입의 절대경로로 반환
파일의 상위 추상경로명을 File 타입의 절대경로로 반환
상위 경로명이 없다면 null을 반환
String
File
getCanonicalPath()
getCanonicalFile()
파일의 추상경로명을 String 타입의 정규경로 반환
파일의 추상경로명을 File 타입의 정규경로 반환

- UI와 운영체제는 파일이나 디렉터리의 이름을 정할 때 시스템에 의존적인 경로명을 사용함 → 윈도우는 경로를 구분할 때 ";", 이름을 구분할 때 "\"를 사용하지만 유닉스는 경로를 구분할 때 ":", 이름을 구분할 때 "/"를 사용

- 절대경로는 파일시스템의 루트에서 시작하는 파일의 전체 경로, 정규경로는 기호나 링크 등을 포함하지 않은 유일한 경로

- 추상경로명은 절대경로일 수도 있고 상대경로명일 수도 있음

- 이로 인해 윈도우에서 만든 Java 코드를 유닉스에서 실행할 때, 반대의 경우일 때 오류를 일으킬 수 있음 → File 클래스는 경로명을 계층적인 관점에서 운영체제에 독립되도록 도와줌

- 시스템 속성 중 user.dir값을 확인하면 현재 실행중인 디렉터리의 상대경로를 알 수 있음

타입 메소드 설명
boolean canRead() 읽을 수 있는 파일인지 검사
boolean canWrite() 쓸  수 있는 파일인지 검사
boolean canExecute() 실행할 수 있는 파일인지 검사
int compareTo(File pathname) 주어진 파일 또는 디렉터리와 비교
Unix는 대소문자 구별, Windows는 구별하지 않음
boolean exists() 파일이 존재하는지 검사
boolean isAbsolute() 파일 또는 디렉터리가 절대경로명으로 지정되었는지 확인
boolean isDirectory() 디렉토리인지 확인
boolean isFile() 파일인지 확인
boolean isHidden() 파일의 속성이 숨김인지 확인. 파일이 없으면 false
boolean createNewFile() 새로운 파일을 생성. 생성하려는 파일이 기존재하면 생성하지 않음.
static File createTempFile() 임시파일을 시스템의 임시 디렉토리에 생성
static File createTempFile(String prefix, String suffix) 임시파일을 시스템의 지정된 디렉토리에 생성
boolean delete() 파일을 삭제
void deleteOnExit() 응용프로그램 종료시 파일을 삭제
boolean equals(Object obj) 주어진 객체가 같은 파일인지 비교
long lastModified() 파일이 마지막으로 수정된 시간을 지정된 시간으로 반환
long length() 파일의 크기를 반환
String[] list() 디렉토리의 파일 목록(디렉토리 포함) String배열로 반환
String[]
File[]
list(FilenameFilter filter)
list(FilenameFilter filter)
FilnameFilter인스턴스에 구현된 조건에 맞는 파일을 String배열(File배열) 반환
File[]
File[]
File[]
listFiles()
listFiles(FileFilter filter)
listFiles(FilenameFilter f)
디렉토리의 파일목록(디렉토리 포함) File배열로 반환(filter 지정된 경우에는 filter 조건과 일치하는 파일만 반환)
static File[]
long
long
long
listRoots()
getFreeSpace()
getTotalSpace()
getUsableSpace()
컴퓨터 파일시스템의 root 목록(floppy, CD-ROM, HDD drive) 반환. get으로 시작하는 메서드들은 File root  비어있는 공간, 전체 공간, 사용가능한 공간을 바이트단위로 반환
boolean
boolean
mkdir()
mkdirs()
파일에 지정된 경로로 디렉토리(폴더) 생성. 성공하면 true, mkdirs 필요하면 부모 디렉토리까지 생성
boolean renameTo(File dest) 지정된 파일(dest) 이름을 변경
boolean
boolean
boolean
boolean
boolean
boolean
boolean
setExcecutable(boolean executable)
setExecutable(boolean executable, boolean ownerOnly)
setReadable(boolean readable)
setReadable(boolean readable, boolean ownerOnly)
setReadOnly()
setWritable(boolean writable)
setWritable(boolean, boolean)
파일의 속성을 변경. OwnerOnly true 파일의 소유자만 해당 속성을 변경할  있음.
boolean setLastModified(long t) 파일을 마지막으로 수정한 시간을 지정된 시간(t)으로 변경
Path toPath() 파일을 Path 변환해서 반환
URI toURI() 파일을 URI 변환해서 반환