java.sql.DriverManager 클래스

- DriverManager JDBC드라이버를 관리하기 위한 기본적인 클래스

- 데이터베이스 드라이버를 선택하고 새로운 데이터베이스 연결을 생성하는 기능을 한다.

- JDBC 4.0 (자바 6) 이상은 classpath 내의 JDBC드라이버가 자동으로 로드 되므로 Class.forName() 메소드를 사용하여 명시적으로 로드 하지 않아도 되지만, JDBC 4.0 미만은 수동으로 JDBC 드라이버를 로딩해야 한다.

 

java.sql.Connection 인터페이스

- 특정 데이터베이스 (DBMS) 와의 연결(session)을 나타내는 객체이다.

- Connection 객체는 쿼리를 실행하는 Statement, PreparedStatement 등의 객체를 생성하거나 COMMIT, ROLLBACK 등의 트랜잭션 처리를 위한 메소드를 제공한다.

- Connection의 객체는 DriverManager.getConnection() 메소드를 호출하여 얻는다.

import java.sql.Connection;
import java.sql.DriverManager;

// Singleton Pattern
public class DBConn {
	private static Connection conn;
	
	private DBConn() {		
	}

	public static Connection getConnection() {
		String url = "jdbc:oracle:thin:@//127.0.0.1:1521/xe"; // 12C 이상
		String user = "유저";
		String pwd = "비밀번호";
		
		if(conn == null) {
			try {
				Class.forName("oracle.jdbc.driver.OracleDriver"); // JDK 7부터 생략 가능
				conn = DriverManager.getConnection(url, user, pwd);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return conn;
	}

	public static void close() {
		if(conn != null) {
			try {
				if(! conn.isClosed()) {
					conn.close();
				}
			} catch (Exception e) {
			}
		}
		
		conn = null;
		
	}
	
}

오라클과 연동하는 것을 클래스로 짜두면 나중에 클래스만 불러와서 하면되므로 편하다.

직렬화(Serialization)

- 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 자바 외부에서도 사용할 수 있도록 바이트(byte)단위로 변환하는 것을 말한다.

- 직렬화가 가능한 자료형 및 객체

  기본형 타입 (boolean, char, byte, short, int, long, float, double)

  Serializable 인터페이스를 구현한 클래스의 객체

  transient가 사용된 멤버변수(null 전송), static 멤버변수, 메소드는 직렬화 대상에서 제외된다.

 

역 직렬화(Deserialization)

- 직렬화된 바이트(byte)단위의 데이터를 다시 원래 데이터로 복원하는 것을 말한다.

 

java.io.Serializable 인터페이스

- 객체를 직렬화하기 위해서는 먼저, 객체를 직렬화가 가능하도록 Serializable 인터페이스를 구현해야 한다.

- 이 인터페이스는 객체 직렬화가 제공되어야 함을 자바 가상 머신에 알려주는 역할을 한다.

- Serializable 인터페이스는 다른 인터페이스와는 달리 구현해야 할 메소드가 없으므로 단지 Serializable 인터페이스만 implements 하면 된다.

- 객체의 직렬화 대상에서 제외되는 것은 멤버 변수가 static으로 선언된 경우, 멤버 변수가 transient로 선언된 경우와 메소드이다.

 

형식

public class 클래스명 implements Serializable {

 // 클래스 정의 부분

}

 

transient

- 직렬화 대상에서 제외할 멤버 변수는 transient 키워드를 사용하여 제외한다.

- transient 키워드가 붙은 멤버 변수가 복원되면, 숫자변수는 0, 객체는 null로 설정된다.

public class 클래스명 implements Serializable {

 접근제어자 자료형 변수1;

 접근제어자 transient 자료형 변수2;

 // 클래스 구현

}

 

SerialVersionUID 필드

- serialVersionUID 는 직렬화에 사용되는 고유 아이디로, 선언하지 않으면 JVM에서 디폴트로 자동생성된다.

  serialVersionUID는 역 직렬화 해서 읽어 들일 때 캐스팅한 클래스의 serialVersionUID와 역직렬화 한 serialVersionUID가 맞는지 확인하기 위해 사용된다.

- 선언하지 않아도 동작하는데 문제는 없지만, JVM에 의한 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에 컴파일러 구현체에 따라서 달라질 수 있어 역 직렬화(deserialization) 과정에서 예상하지 못한 InvalidClassException을 유발할 수 있다. 

- Java에서는 명시적으로 serialVersionUID를 선언할 것을 적극 권장하고 있다.

- 선언 예

private static final long serialVersionUID = 1L;

 

예시>>

더보기

Main

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Ex004_transient {
	public static void main(String[] args) {
		UserService ov = new UserService();
		ov.saveFile();
		ov.loadFile();
	}
}

 

Class

// Serializable : 직렬화
// 직렬화에서 제외되는 것 : 메소드, static 변수, transient 변수

class UserDTO implements Serializable { // 바이트로 고쳐서 저장해줌
	private static final long serialVersionUID = 1L; // 같은 클래스인지아닌지 확인용도
	
	private String name;
	private transient String tel; // 직렬화에서 제외됨. 네트워트로 전송이 되지 않음.
	private int age;

	public UserDTO() {
		
	}
	
	public UserDTO(String name, String tel, int age) {
		this.name = name;
		this.tel = tel;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

class UserService {
	private String pathname = "object2.txt";
	
	public void loadFile() {
		try( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname))) {
			
			System.out.println("파일 내용...");
			while(true) {
				UserDTO vo = (UserDTO) ois.readObject(); // 역직렬화수행
				System.out.println(vo.getName()+"\t"+vo.getTel()+"\t"+vo.getAge());
			}
			
		} catch (EOFException e) {
			// ObjectInputStream 스트림은 파일의 내용을 더 이상 읽을 수 없으면
			// EOFException 예외가 발생한다. 따라서 EOFException 예외를 catch하고
			// 아무런 코드도 작성하지 않는다. // 안잡으면 터짐
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void saveFile() {
		// ObjectOutputStream : Serializable 인터페이스가 구현되어 있어야 저장가능하다.
		try ( ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pathname))){

			oos.writeObject(new UserDTO("다자바", "010-0000-0000", 20));
			oos.writeObject(new UserDTO("너자바", "010-1111-0000", 20));
			oos.writeObject(new UserDTO("구자바", "010-2222-0000", 20));
			
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

java.io.ObjectOutputStream

- ObjectOutputStream 클래스는 객체들을 출력하는 기능을 제공하는 클래스로 출력 스트림에 출력하기 전에 직렬화를 수행한다.

- 파일이나 네트워크로 데이터를 전송하기 위해 직렬화를 수행하며, 이때 writeObject() 메소드를 사용하여 변환한다.

- 스트림에 저장할 수 있는 객체는 Serializable 인터페이스를 구현한 클래스의 객체만 가능하다.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;

public class Ex001_ObjectOutputStream {

	public static void main(String[] args) {
		Hashtable<String, String> ht = new Hashtable<String, String>();
		
		ht.put("자바", "프로그래밍");
		ht.put("HTML", "웹 프로그래밍");
		ht.put("오라클", "데이터베이스");
		
		String pathname = "object.txt";
		ObjectOutputStream oos = null;
		
		try {
			// ObjectOutputStream : 객체를 저장 할 수 있는 스트림
			// 객체를 저장하면 파일 선두에는 객체의 클래스명이 저장된다.
			oos = new ObjectOutputStream(new FileOutputStream(pathname));
			oos.writeObject(ht);
			System.out.println("파일 저장 완료...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(oos !=null ) {
				try {
					oos.close();
				} catch (Exception e2) {
				}
			}
		}
		
	}

}

 

위 코드를 실행하면 object.txt 파일이 저장되고 안에는 이렇게 되어있다.


java.io.ObjectInputStream

- ObjectOutputStream 클래스에 의해 파일에 저장되거나 네트워크를 통해 전달된 객체의 직렬화를 해제하는 기능을 제공한다.

- 파일이나 네트워크를 통해 받은 직렬화된 데이터를 다시 원래 데이터로 복원하는 역할을 하며, 이때 readObject() 메소드를 사용하여 복원한다.

- readObject() 메소드를 통해 읽어 들인 데이터는 원래 데이터로 캐스팅하여 사용한다.

- 스트림으로부터 읽어들일 수 있는 객체는 Serializable 인터페이스나 Externalizable 인터페이스를 구현한 클래스의 객체만 가능하다.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Hashtable;
import java.util.Iterator;

public class Ex002_ObjectInputStream {

	public static void main(String[] args) {
		String pathname = "object.txt";
		
		try ( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname))){
			// 제너릭은 다운 캐스팅하면 경고가 나옴.
			@SuppressWarnings("unchecked") // 경고없앰
			Hashtable<String, String> ht = (Hashtable<String, String>)ois.readObject();
			
			Iterator<String> it = ht.keySet().iterator();
			while(it.hasNext()) {
				String key = it.next();
				String value = ht.get(key);
				System.out.println(key+" -> "+value);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

위에서 만든 object.txt파일을 읽어들인 결과

Hashtable 은 Map의 구현 클래스로 동기화를 지원한다.

Map은 <키, 값>의 구조로 키는 중복을 허용하지 않는다. 키는 순서가 없으므로 반복자도 존재하지 않는다.

java.io.DataInputStream 클래스

- 기본 Java 데이터 유형을 플랫폼에 독립적인 방법으로 기본 입력 스트림에서 읽을 수 있다.

- 필터 스트림이기 때문에 다른 입력 스트림을 생성자의 인자로 받아 객체를 생성한다.

- InputStream, FilterInputStream의 하위 클래스

import java.io.DataInputStream;
import java.io.FileInputStream;

public class Ex016_DataInputStream {

	public static void main(String[] args) {
		
		// DataOutputStream으로 저장한 내용은 DataInputStream으로 읽어야 한다.
		// 저장한 자료형 순서대로 읽어 들인다.
		// 더 이상 읽을 데이터가 없으면 IOException이 발생된다.
		try(DataInputStream dis = new DataInputStream(new FileInputStream("text.txt"))) {
			System.out.println(dis.readUTF());
			System.out.println(dis.readByte());
			System.out.println(dis.readChar());
			System.out.println(dis.readInt());
			System.out.println(dis.readInt());
			System.out.println(dis.readUTF());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}


java.io.DataOutputStream 클래스

- 기본 Java 데이터 유형을 출력하는 기능을 가진 클래스로 필터 스트림이기 때문에 다른 출력 스트림을 생성자의 인자로 받아 생성한다.

- OutputStream, FilterOutputStream의 하위 클래스

 

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Ex015_DataOutputStream {

	public static void main(String[] args) {
		try(DataOutputStream dos = new DataOutputStream(new FileOutputStream("text.txt"))) {
			dos.writeUTF("서울");
			dos.writeByte(10);
			dos.writeChar('A');
			dos.writeInt(50);
			dos.writeInt(70);
			dos.writeUTF("서울");
			
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}


필터 스트림 ?

- 필터 스트림은 기존의 스트림을 원하는 기능을 제공하는 새로운 스트림으로 바꾸어 주는 스트림이다.

- 필터 스트림의 최상위 클래스에는 FilterInputStream과 FilterOutputStream클래스가 있다.

 

FilterInputStream과 FilterOutputStream 클래스

- 이 클래스를 인스턴스 한 객체는 매개변수로 입력 받은 다른 스트림과 연결되어있다.

- 실제 데이터 소스에서 스트림을 처리하는 것이 아니라 다른 스트림과 연결하는 용도로 사용된다.

따라서 입/출력 스트림에서 받은 데이터를 다른 데이터로 변환하거나 추가 작업을 하는 클래스이다.

java.io.BufferedReader 클래스

- 문자, 배열 및 행을 효율적으로 읽을 수 있도록 문자를 버퍼링하여 문자 입력 스트림에서 텍스트를 읽어들인다.

- 버퍼 크기를 지정하거나 기본 크기(8192byte)를 사용한다.

- Reader 하위 클래스

 

java.io.BufferedWriter 클래스

- 다른 출력 스트림을 생성자의 인자로 받아 생성하며 버퍼링 하는 것에 따라 문자, 배열 또는 스트링을 문자 형태로 출력 스트림에 출력한다.

- Writer 하위 클래스

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;

// BufferedWriter : 문자를 버퍼링하여 문자 출력 스트림에 저장
public class Ex014_BufferedWriter {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s;
		
		try ( BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"))){
			System.out.println("문자열 입력[종료:ctrl+z]....");
			while( (s = br.readLine()) != null) {
				bw.write(s);
				bw.newLine(); // 이거 있어야 Line이 넘어감
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 - user.txt 파일을 읽어서 합격자만 pass.txt에 저장하는 프로그램 작성
 - user.txt 파일 형식
   이름,국,영,수
 - pass.txt 파일 형식
   이름,국,영,수
 - 세과목 모두 40점 이상이고 평균이 60점 이상인 경우만 합격자
 - pass.txt에 저장할 때는 총점 내림차순으로 저장(단, 이것은 못하겠으면 안해도 됨)
 - UserDTO 만들고, UserPass 라는 클래스를 만들어서 작성할 것
 - ArrayList 사용하면 쉽다. (Map 사용 안함)
 - 작성할 수 있는데 까지 작성해서 메일로 보내기

 

Main

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;

public class Ex012_PassUser {
	public static void main(String[] args) {
		UserPass vo = new UserPass();
		
		vo.loadfile();
		vo.savefile();
		System.out.println("파일 생성 완료...");
		
	}
}

Class

class UserDTO {
	private String name;
	private Integer kor;
	private Integer eng;
	private Integer mat;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getKor() {
		return kor;
	}

	public void setKor(Integer kor) {
		this.kor = kor;
	}

	public Integer getEng() {
		return eng;
	}

	public void setEng(Integer eng) {
		this.eng = eng;
	}

	public Integer getMat() {
		return mat;
	}

	public void setMat(Integer mat) {
		this.mat = mat;
	}

}

class UserPass {
	private ArrayList<UserDTO> list = new ArrayList<>();
	private String pathname1 = "user.txt";
	private String pathname2 = "pass.txt";

	
	public void loadfile() {
		try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
			String s;
			while ( (s = br.readLine()) != null ) {
				String [] ss = s.split(",");
				
				if(ss.length < 2) {
					continue;
				}
				UserDTO vo = new UserDTO();
				vo.setName(ss[0]);
				
				int kor, eng, mat, tot;
				long ave;
				kor = Integer.parseInt(ss[1]);
				eng = Integer.parseInt(ss[2]);
				mat = Integer.parseInt(ss[3]);
				
				tot = kor+eng+mat;
				ave = tot / 3 ;
				if ( ave >=60 && (kor>=40 && eng>=40 && mat >=40)) {
					vo.setKor(kor);
					vo.setEng(eng);
					vo.setMat(mat);
					
					list.add(vo);
					
				} else {
					continue;
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void savefile() {
		try(PrintStream ps = new PrintStream(pathname2)) {
			Iterator<UserDTO> it = list.iterator();
			
			while(it.hasNext()) {
				UserDTO vo = it.next();
				ps.println(vo.getName()+"\t"+vo.getKor()+"\t"
							+vo.getEng()+"\t"+vo.getMat());
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

총점 내림차순은

 

혼자서 해보다가 못했음.

내가 하려고 했던 방법은,

1) int[] 를 만들어서 총점을 담는다.

2) list.add 할 때 만 총점 배열에 총점을 넣음. 그래야 출력(합격자)할 자료들만 모아지니까

3) list.add 가 끝나면 그 배열을 선택정렬을 통해 정렬할때 리스트도 list.set() 으로 바꿈.

 

너무 길어져서 >>

더보기
int [] total = new int[] {list.size()};
int count = 0;

total[count++] = tot;

UserDTO vo2;
int c;

for (int i = 0; i<list.size() -1 ; i++){
	for(int j = i+1; i<list.size() ; j++){
		if(total[i] < total[j]){
        	c = total[i];
            total[i] = total[j];
            total[j] = c;
            
        	vo2 = list.get(i);
            list.set(i, list.get(j));
            list.set(j, vo2);
        }
    }
}

 

원래 합격자들만 출력한 결과는

이것인데 총점 내림차순은 못했음.

public void loadfile() {
		int [] total = new int[] {list.size()};
		try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
			String s;
			while ( (s = br.readLine()) != null ) {
				String [] ss = s.split(",");
				
				if(ss.length < 2) {
					continue;
				}
				UserDTO vo = new UserDTO();
				vo.setName(ss[0]);
				
				int kor, eng, mat, tot;
				long ave;
				kor = Integer.parseInt(ss[1]);
				eng = Integer.parseInt(ss[2]);
				mat = Integer.parseInt(ss[3]);
				
				tot = kor+eng+mat;
				ave = tot / 3 ;
				if ( ave >=60 && (kor>=40 && eng>=40 && mat >=40)) {
					vo.setKor(kor);
					vo.setEng(eng);
					vo.setMat(mat);
					
					list.add(vo);
					
					int count = 0;
					
					total[count++] = tot;
					
					
				} else {
					continue;
				}
				
				UserDTO vo2;
				int c;

				for (int i = 0; i<total.length-1 ; i++){
					for(int j = i+1; i<total.length ; j++){
						if(total[i] < total[j]){
							c = total[i];
							total[i] = total[j];
							total[j] = c;
							
							vo2 = list.get(i);
							list.set(i, list.get(j));
							list.set(j, vo2);
						}
					}
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

이렇게 하니까 안터지긴 하는데 결과가 정렬부분 있든 없든 똑같음...

 

그럼

아예 UserDTO 에 총점입력하는 칸을 넣어서 하는 것이 어떨까? 

public class Ex012_PassUser {
	public static void main(String[] args) {
		UserPass vo = new UserPass();

		vo.loadfile();
		vo.sort();
		vo.savefile();
		System.out.println("파일 생성 완료...");

	}
}

class UserDTO {
	private String name;
	private Integer kor;
	private Integer eng;
	private Integer mat;
	private Integer tot;

	public Integer getTot() {
		return tot;
	}

	public void setTot(Integer tot) {
		this.tot = tot;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getKor() {
		return kor;
	}

	public void setKor(Integer kor) {
		this.kor = kor;
	}

	public Integer getEng() {
		return eng;
	}

	public void setEng(Integer eng) {
		this.eng = eng;
	}

	public Integer getMat() {
		return mat;
	}

	public void setMat(Integer mat) {
		this.mat = mat;
	}

}

class UserPass {
	private ArrayList<UserDTO> list = new ArrayList<>();
	private String pathname1 = "user.txt";
	private String pathname2 = "pass.txt";

	public void loadfile() {
		try (BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
			String s;
			while ((s = br.readLine()) != null) {
				String[] ss = s.split(",");

				if (ss.length < 2) {
					continue;
				}
				UserDTO vo = new UserDTO();
				vo.setName(ss[0]);

				int kor, eng, mat, tot;
				long ave;
				kor = Integer.parseInt(ss[1]);
				eng = Integer.parseInt(ss[2]);
				mat = Integer.parseInt(ss[3]);

				tot = kor + eng + mat;
				ave = tot / 3;
				if (ave >= 60 && (kor >= 40 && eng >= 40 && mat >= 40)) {
					vo.setKor(kor);
					vo.setEng(eng);
					vo.setMat(mat);
					vo.setTot(tot);

					list.add(vo);

				} else {
					continue;
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void savefile() {
		try (PrintStream ps = new PrintStream(pathname2)) {
			Iterator<UserDTO> it = list.iterator();

			while (it.hasNext()) {
				UserDTO vo = it.next();
				ps.println(vo.getName() + "\t" + vo.getKor() 
						+ "\t" + vo.getEng() + "\t" + vo.getMat());
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sort() {
		UserDTO vo2;
		for (int i = 0; i < list.size() - 1; i++) {
			for (int j = i + 1; j < list.size(); j++) {
				if(list.get(i).getTot() < list.get(j).getTot()) {
					vo2 = list.get(i);
					list.set(i, list.get(j));
					list.set(j, vo2);
				}
			}
		}
	}
}

 예!! 이렇게 정렬하는 것을 따로 메소드로 만들어서 거기서 총점을 가지고 바꾸는 것을 해보았다.

예! 총점은 확인용으로 출력해보았다.

 

앗싸 - 이게 맞는지는 내일 수업을 듣고 업데이트 하겠다.

 

총점 내림 차순 추가

Main

public class Ex012_PassUser {
	public static void main(String[] args) {
		UserPass vo = new UserPass();

		vo.loadfile();
		vo.sort();
		vo.savefile();
		System.out.println("파일 생성 완료...");

	}
}

Class

class UserDTO {
	private String name;
	private Integer kor;
	private Integer eng;
	private Integer mat;
	private Integer tot;

	public Integer getTot() {
		return tot;
	}

	public void setTot(Integer tot) {
		this.tot = tot;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getKor() {
		return kor;
	}

	public void setKor(Integer kor) {
		this.kor = kor;
	}

	public Integer getEng() {
		return eng;
	}

	public void setEng(Integer eng) {
		this.eng = eng;
	}

	public Integer getMat() {
		return mat;
	}

	public void setMat(Integer mat) {
		this.mat = mat;
	}

}

class UserPass {
	private ArrayList<UserDTO> list = new ArrayList<>();
	private String pathname1 = "user.txt";
	private String pathname2 = "pass.txt";

	public void loadfile() {
		try (BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
			String s;
			while ((s = br.readLine()) != null) {
				String[] ss = s.split(",");

				if (ss.length < 2) {
					continue;
				}
				UserDTO vo = new UserDTO();
				vo.setName(ss[0]);

				int kor, eng, mat, tot;
				double ave;
				kor = Integer.parseInt(ss[1]);
				eng = Integer.parseInt(ss[2]);
				mat = Integer.parseInt(ss[3]);

				tot = kor + eng + mat;
				ave = tot / 3;
				if (ave >= 60 && (kor >= 40 && eng >= 40 && mat >= 40)) {
					vo.setKor(kor);
					vo.setEng(eng);
					vo.setMat(mat);
					vo.setTot(tot);

					list.add(vo);

				} else {
					continue;
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void savefile() {
		try (PrintStream ps = new PrintStream(pathname2)) {
			Iterator<UserDTO> it = list.iterator();

			while (it.hasNext()) {
				UserDTO vo = it.next();
				ps.println(vo.getName() + "\t" + vo.getKor() 
						+ "\t" + vo.getEng() + "\t" + vo.getMat());
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sort() {
		UserDTO vo2;
		for (int i = 0; i < list.size() - 1; i++) {
			for (int j = i + 1; j < list.size(); j++) {
				if(list.get(i).getTot() < list.get(j).getTot()) {
					vo2 = list.get(i);
					list.set(i, list.get(j));
					list.set(j, vo2);
				}
			}
		}
	}
}

user.txt
pass.txt

 

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public class Ex008_Encoding {

	public static void main(String[] args) {
		// MS949(euc-kr 유사) 데이터를 UTF-8 형식의 파일로 저장하기
		int data;
		String pathname = "test.txt";
		
		// 파일에 내용을 문자 출력 스트림. 인코딩은 UTF-8
		try (Writer wt = new OutputStreamWriter(new FileOutputStream(pathname), "UTF-8") ){
			// 바이트 스트림을 문자 스트림으로 바꿈
			// byte 스트림을 문자 스트림으로. 인코딩은 MS949
			Reader rd = new InputStreamReader(System.in, "MS949");
			
			// Reader rd = new InputStreamReader(System.in); // 시스템에 설정된 기본 인코딩

			System.out.println("입력[종료:ctrl+z]...");
			while( (data = rd.read()) != -1) {
				wt.write(data);
			}
			wt.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

문자 스트림을 다루기 때문에 내용을 보낼 때 Writer, 내용을 받을 때 Reader 를 사용한다.

여기서는 키보드를 통해 입력받은 것을 test.txt로 저장한다.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public class Ex009_Encoding {

	public static void main(String[] args) {
		// UTF-8 파일을 MS949 파일로 복사하기
		String source = "test.txt";
		String dest = "ex.txt";
		
		int data;
		try(Reader rd = new InputStreamReader(new FileInputStream(source), "UTF-8");
			Writer wt = new OutputStreamWriter(new FileOutputStream(dest), "MS949")	
			) {
			
			while( (data = rd.read()) != -1) {
				wt.write(data);
			}
			wt.flush();
			
			System.out.println("변환 저장 완료...");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

위에서 test.txt 저장한 것을 MS949로 변환시켜준다.

import java.io.BufferedReader;
import java.io.File;
// import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Ex003_Cat { // 텍스트파일 안에 들어있는 내용을 확인하는 리눅스 명령어
	// ls 파일목록 확인
	public static void main(String[] args) {
		// 텍스트 파일 내용 읽기
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		String pathname;
		String s;
		
		BufferedReader fbr = null;
		
		try {
			System.out.print("파일명 ? ");
			pathname = br.readLine();
			
			File f = new File(pathname);

/*			if( ! f.exists()) {
				System.out.println("파일이 존재하지 않습니다.");
				System.exit(0);
			}
*/
			// byte 스트림 -> InputStreamReader -> 문자 스트림
			// fbr = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
			// fbr = new BufferedReader(new InputStreamReader(new FileInputStream(pathname)));
			// 바이트 스트림 -> 문자로 고침
			// fbr = new BufferedReader(new FileReader(pathname));
			fbr = new BufferedReader(new FileReader(f));
			// Reader 는 한 문자를 입력 받을 수 있다.
			while( (s = fbr.readLine()) != null) {
				System.out.println(s);
			}
			
		} catch (FileNotFoundException e) {
			System.out.println("파일이 존재하지 않습니다.");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(fbr != null) {
				try {
					fbr.close();
				} catch (Exception e2) {
				}
			}
		}
		
	}

}

텍스트 파일안에 있는 문자들을 읽어서 화면에 출력해준다.

+ Recent posts