본문 바로가기

Computer Science/Data Structures & Algorithms

[Lecture 0 - I] Java File I/O

#File Class

파일 및 디렉터리 경로 이름의 추상 표현

File(String pathname)

유용한 method들: 

boolean exists()
boolean createNewFile()
boolean delete()
long length()

 

텍스트 파일의 데이터 읽기/쓰기에 유용한 클래스와 방법을 알아보자.

텍스트 파일은 모든 데이터 값이 일련의 문자(ASCII 또는 유니코드와 같은 일반적인 체계에서 인코딩됨)로 표현되는 파일이다.

이진 파일은 모든 데이터 값이 기계 메모리에서 이를 나타내는 데 사용되는 동일한 비트 패턴으로 표현되는 파일이다.

#FileWriter 클래스

텍스트 파일에 순차적으로 쓰기 위해서는 일반적으로 FileWriter 클래스로 충분하다

FileWriter(String fileName)
FileWriter(File file)

유용한 method들: 

void write(char[] cbuf)
void write(char[] cbuf, int offset, int length)
void write(String str)
void flush()
void close()

#FileReader 클래스

반대로 텍스트 파일에 순차적으로 읽기 위해서는 일반적으로 FileReader 클래스로 충분하다

FileReader(String fileName)
FileReader(File file)

유용한 method들:

int read()
int read(char[] cbuf)
int read(char[] cbuf, int offset, int length)
void close()

#RandomAccessFile 클래스

임의 액세스 파일에 대한 읽기/쓰기를 지원한다. 동일한 파일을 읽고 써야 하거나 파일 내에서 선택한 위치를 검색한 다음 해당 파일을 읽거나 써야 할 때 매우 유용하다

RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)
mode: “r” “rw” (“rws” “rwd”)
  • 논리적 관점은 기본 파일이 바이트의 시퀀스(즉, 배열)라는 것이다.
  • 각 바이트는 파일의 시작부터 고유한 오프셋에서 발생한다.
  • 파일 내의 현재 위치에 대한 내부 파일 포인터를 유지한다.
  • 읽기/쓰기시 파일 포인터는 움직인다.
  • 파일 끝에 쓰면 파일이 확장된다.
  • 유용한 method들:
    • int read()
    • int read(byte[] b)
    • int read(char[] cbuf, int offset, int length)
    • String readLine()
    • void write(byte[] b)
    • void write(byte[] b, int offset, int length)
    • long length()
    • int getFilePointer()
    • void seek(long offset)
    • void close()

RandomAccessFile 예시

public class rafExample {
     public static void main(String[] args) {
         try {
             long offset = 0;
             RandomAccessFile raf = new RandomAccessFile(args[0], "r");
             //Get the position of the first record (should be 0):
             offset = raf.getFilePointer();
             //Grab first line (first complete record):
             String record = raf.readLine();
             //Tell the world:
             System.out.println("The record offset is: " + offset);
             System.out.println("The record is: " + record);
         } catch (FileNotFoundException e) {
         System.err.println("Could not find file: " + args[0]);
         } catch (IOException e) {
         System.err.println("Writing error: " + e);
         }
     }
}

#Scanner 클래스

정규식을 사용하여 primitive type 및 문자열을 구문 분석할 수 있는 간단한 텍스트 스캐너이다.

스캐너는 기본적으로 공백과 일치하는 구분 기호 패턴을 사용하여 입력을 토큰으로 나눈다. 결과 토큰들은 다양한 다음 방법들을 사용하여 상이한 유형의 값들로 변환될 수 있다.

Scanner(InputStream source)
Scanner(String source)

Configuration: useDelimiter(String pattern)

유용한 method들:

String next()
byte nextByte()
int nextInt()
. . .
boolean hasNext()         boolean hasNextByte()
boolean hasNextInt()     boolean hasNextLine()
 . . .
void close()

 

Scanner 예시:

public class scannerExample {
 public static void main(String[] args) {
 String line = "foo\tbar\twidget";

 Scanner s = new Scanner(line);
 s.useDelimiter("\t");
 String token1 = s.next();
 String token2 = s.next();
 String token3 = s.next();

 System.out.println(token1 + " " + token2 + " " + token3);
 }
}

#String 메소드 split()

// Pre:
// row is a string made up of comma-separated integer values
//
public int sumRow( String row ) {
 int sum = 0;

 String[] values = row.split(",");
 for (int idx = 0; idx < values.length; idx++) {
 sum += Integer.parseInt( values[idx] );
 }
 return sum;
}

만약 row가 "18, -5, 10, 7, 25" 이라고 가정하면

values는 다음과 같다

#Formatter 클래스

class Buffer {
 long offset;
 String data;
 boolean dirty;
 . . .
 public String toString() {
 Formatter f = new Formatter();
 f.format("%12d: ", offset);
 return ( f.toString() + data );
 }
}