java.io.RandomAcessFile

RandomAcessFile는 Object 클래스의 한단계 하위 클래스로 파일의 읽기, 쓰기가 가능하다.

파일시스템에 바이트로 저장된 큰 배열에 접근하는 방법으로 순차적으로 접근하는 방법이 아니라 파일 포인터를 이용해 임의의 위치(사용자가 선택한 인덱스)를 바로 읽을 수 있는 클래스이다.


Constructor:생성자

1. RandomAccessFile(File file, String mode)

2. RandomAccessFile(String name, String mode)

* mode

"r" -> 읽기전용

"rw" -> 읽고 쓰기 가능

"rws" ->

 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 Android

 SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3(Jelly Bean)

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


문제점

안드로이드에서 파일 출력을 하려는데 openFileOutput에서 에러가 발생했다.

"The method openFileOutput(String, int) is undefined for the type LocationData" 라고 정의되어 있지 않다고 한다.


해결방안

openFileOutput()는 Context 클래스에 있는 메서드인데 파일출력을 하는 클래스를 따로 만들었을땐 문제가 발생한다.

그러므로, 파일 출력 클래스에서 Context를 선언해주어야 한다.

(혹시 몰라 MainActivity에 있는 Context를 그대로 가져왔습니다. 문제 없다면 댓글 부탁바랍니다.)


MainActivity.java

...
Context mContext;
mContext =  getApplicationContext();
data.textFileSave(mContext);
...

LocationData.java(파일출력 클래스)

...
public void textFileSave(Context cont) {
FileOutputStream fos = null;
	try {
		// 기본 파일 저장
		fos = cont.openFileOutput("test.txt", Context.MODE_APPEND);
		for.write(toString().getBytes());
		...
	} catch (Exception e) {}
}
...


 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


직렬화하지 않은 파일 읽기, 쓰기 

- API : FileReader, BufferedReader, FileWriter, BufferedWriter

읽기, 쓰기작업을 처리하는 FileReader, FileWriter에 효율을 향상시켜주는 BufferedReader, BufferedWriter 클래스를 연쇄시켜 사용한다. 버퍼는 자신이 가득 찰 때까지 기다리다가 꽉찬 후에 작업이 진행한다.


[JAVA] java.io.File 클래스


쓰는 방법(출력)

BufferedWriter w = new BufferedWriter(new FileWriter(new File("FileTest.txt")));

버퍼가 가득차기전에 데이터를 보내고자 한다면 writer.flush() 호출한다.


읽는 방법(입력)

읽기작업은 while()문에서 한번에 한 행씩 읽어오며, readLine()에서 null을 리턴하면 반복문을 종료한다.

가장 흔하게 쓰이는 방법

import java.io.*;

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName1 = "FileTest.txt";
		File f;

		try {
			// File 객체 생성(존재하는 파일)
			f = new File(fDir + fName1);

			// 파일 쓰기(주석부분은 간략화)
			FileWriter fileWriter = new FileWriter(f);
			BufferedWriter writer = new BufferedWriter(fileWriter);
			//BufferedWriter writer = new BufferedWriter(new FileWriter(f));

			writer.write("witerTest1");
			writer.append("\n"); // 개행문자 삽입
			writer.append("witerTest2");
			writer.newLine(); // 개행 메서드
			writer.write("witerTest3");
			writer.close(); // 파일 닫기

			// 파일 읽기
			FileReader fileReader = new FileReader(f);
			BufferedReader reader = new BufferedReader(fileReader);

			String line = null;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
			reader.close(); // 파일 닫기
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}

	}
}



직렬화된 객체의 파일 입출력

- API : ObjectOutputStream, ObjectInputStream, FileOutputStream, FileInputStream

사진. 구글 검색(Head First Java)


직렬화할 객체

Serializable 인터페이스를 꼭 구현해야한다.

class TestSerialization implements Serializable {
	private int x;
	private String str;

	TestSerialization(int a) { this.x = a; }
	TestSerialization(String s) { this.str = s;	}

	int getA() { return x; }
	String getS() {	return str;	}
}

파일 저장하기(출력)

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName = "FileTest.ser";

		FileOutputStream fileStream;
		ObjectOutputStream objStream = null;

		// 저장할 객체
		TestSerialization test1 = new TestSerialization("ObjectTest1");
		TestSerialization test2 = new TestSerialization(100);
		TestSerialization test3 = new TestSerialization("ObjectTest3");

		try {
			// 파일에 연결하기위해 생성, 파일명의 파일이 없으면 새로 만들어줌.
			fileStream = new FileOutputStream(fDir + fName);
			objStream = new ObjectOutputStream(fileStream);

			// 출력되는 객체는 반드시 Serialization 인터페이스 구현
			objStream.writeObject(test1);
			objStream.writeObject(test2);
			objStream.writeObject(test3);
			
			System.out.println("end");

		} catch (Exception ex) {
			System.err.println("Exception : " + ex.getMessage());
		} finally {
			try {
				objStream.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}

파일 불러오기(입력) : 역직렬화(객체 복구)

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName = "FileTest.ser";

		FileInputStream fileStream;
		ObjectInputStream objStream = null;
		
		try {
			// 역직렬화할 파일을 불러온다.
			fileStream = new FileInputStream(fDir + fName);
			objStream = new ObjectInputStream(fileStream);

			// 처음에 저장된 순서대로 가져온다.
			Object one = objStream.readObject();
			Object two = objStream.readObject();
			Object three = objStream.readObject();
			
			// 역직렬화할 객체
			TestSerialization test1 = (TestSerialization) one;
			TestSerialization test2 = (TestSerialization) two;
			TestSerialization test3 = (TestSerialization) three;
			
		} catch (Exception ex) {
			System.err.println("Exception : " + ex.getMessage());
		} finally {
			try {
				objStream.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}



 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


java.io.File 클래스 API

File 클래스는 파일의 내용을 수정하거나 입력하는 클래스가 아니라, 파일이나 디렉토리 자체를 담는 클래스이다.

즉, File 객체는 파일경로명이나 파일명과 비슷한 것으로 생각할 수 있다. 파일에 입력이나 수정을 하려면 File 객체를 FileWriter 또는 FileInputStream 등의 객체에 전달해서 그 객체에서 사용해야 한다.


import java.io.File;

public class FileTest {
	public static void main(String[] args) {
		// File 객체 생성(이미 존재하는 파일)
		File f = new File("FileTest.txt");
		
		// 현재 프로젝트 폴더내에 생성
		File dir = new File("FileTestDir");
		if(dir.mkdir()) {
			// 폴더가 존재하지 않다면
			System.out.println("true");
		} else {
			// 폴더가 존재한다면
			System.out.println("False");
		}
		
		// 파일 또는 디렉토리의 절대 경로명
		System.out.println(f.getAbsolutePath());
		System.out.println(dir.getAbsolutePath());
		
		// 파일 또는 디렉토리 삭제
		boolean deletedCheck = dir.delete();
		System.out.println(deletedCheck != false ? "삭제 성공" : "삭제 실패");
	}
}


'대학 생활 > JAVA' 카테고리의 다른 글

[JAVA] 연산자 우선순위  (0) 2014.05.02
[JAVA] 파일 읽기, 쓰기  (0) 2014.04.16
[JAVA]정적필드, 정적메소드  (0) 2014.03.18
[JAVA] String <-> int, double, float 변환  (0) 2014.02.28
먼저 학번과 성적이 저장된 파일이 존재해야한다.
/*
    목적 : 파일을 읽어 각 반의 학생의 성적과 합계, 평균을
   		  구하고 각 과목의 반평균을 구한다.
    작성날짜 : 2013.09.23
 */
#include <stdio.h>
#include <stdlib.h>

// 상수들 
#define PEPLE_NUM 181	// 총학생수 정의

void openFile(FILE* fp);
void printClass(int class);

// 학생 정보를 저장하기 위한 구조체 선언
typedef struct student{
	char class_st[10];
	int class[3];
	int score[5];
	int total;
	float average;
} Student;

// 모든 함수에서 사용하기 위해 전역부에 선언
Student stu[PEPLE_NUM];

int main(int argc, char *argv[]) {
	
	FILE* fp = fopen("scr2013.txt", "r");
	if (fp == NULL) {
		printf(" File is null.\n");
		return -1;
	}
	openFile(fp);
	fclose(fp);

	printf("┌──────────────────────┐\n");
	printf("│  초등학교 1학년 성적 일람표 출력하기.  │\n");
	printf("└──────────────────────┘\n");

	while(1) {
		int in = 0;
		printf("  어느 반을 출력할 것입니까?(exit=0) : ");
		scanf("%d", &in);

		if(in == 0) {
			printf("program exit...\n");
			break;
		}
		// 성적일람표 출력 함수 실행
		printClass(in);
	} // while

	return 0;
}

/* =============== openFile ======================================
  파일을 읽어서 구조체 배열에 저장하고 총점, 평균 구하는 함수
	사전조건 : main에서 읽은 파일을 배열에 입력하기 위해서
			   매개변수 fp로 받아온다.
 	사후조건 : 구조체 배열에 점수를 입력하고 총점, 평균을 구한다.
 */
void openFile(FILE* fp) {
// 지역정의
	int temp;
	int i;

// 문장들
	// 파일 읽어서 구조체 배열에 입력하기
	for(i=0; i < PEPLE_NUM; i++) {
		fscanf(fp, "%s %d %d %d %d %d", &(stu[i]).class_st, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2], &stu[i].score[3], &stu[i].score[4]);

		// 입력받은 문자열인 학번을 integer로 변환하기 위해 atoi함수를 사용했다.
		temp = atoi(stu[i].class_st);
		stu[i].class[0] = temp / 10000;
		stu[i].class[1] = (temp - (stu[i].class[0] * 10000)) / 100;
		stu[i].class[2] = (temp - (stu[i].class[0] * 10000) - (stu[i].class[1] * 100)) / 1;
	}

	// 입력받은 점수로 총점, 평균 계산하기
	for(i = 0; i < PEPLE_NUM; i++) {
		stu[i].total = stu[i].score[0] + stu[i].score[1] + stu[i].score[2] + stu[i].score[3] + stu[i].score[4];
		stu[i].average = stu[i].total / 5.0;
	}

} // openFile
//================= openFile End =================================


/* =============== printClass  ===================================
   출력하고자 하는 반을 주어진 틀에 맞게 출력하는 함수.
     사전조건 : 출력하고자하는 반을 매개변수로 받는다.
	 사후조건 : 헤더를 출력하고 학생들의 정보를 모두 출력한다.
	 			모두 출력하고 난뒤에 각 과목의 반평균을 출력한다.
 */
void printClass(int class) {
// 지역정의
	int i;
	int count = 0;
	float kor = 0;
	float math = 0;
	float social = 0;
	float science = 0;
	float pe = 0;

// 문장들
	printf("\n  1 학년 %2d 반 성적일람표\n", class);
	printf(" 학번  국어  산수  사회  과학  체육  총점  평균 \n");
	printf("------------------------------------------------\n");
	// 학생 출력.
	for(i = 0; i < PEPLE_NUM ;i++ ) {
		if(stu[i].class[1] == class) {
			printf("%5s  %3d   %3d   %3d   %3d   %3d   %3d   %3.1f \n", stu[i].class_st, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].score[3], stu[i].score[4], stu[i].total, stu[i].average);
			kor += stu[i].score[0];
			math += stu[i].score[1];
			social += stu[i].score[2];
			science += stu[i].score[3];
			pe += stu[i].score[4];
			count++;
		}
	}
	// 학생이 없을 경우 출력.
	if(count == 0) {
		printf("               자료가 없습니다.\n\n");
		return;
	}

	printf("------------------------------------------------\n");
	printf("반평균  %3.1f  %3.1f  %3.1f  %3.1f  %3.1f \n\n", kor/(float)count, math/count, social/count, science/count, pe/count);
} // printClass
//================= printClass End ===============================


+ Recent posts