본문 바로가기

JAVA공부(이것이 자바다)

입출력스트림

 

 

입출력스트림은 forEach로 안도는게 좋다 왜냐면 읽어온 크기만큼 돌아야하는데 내가 읽지 않은 부분까지 순회하게 되기 때문이다.

try {
			InputStream is = new FileInputStream("C:/Temp/test2.db");
			
			byte[] data = new byte[100];

			while(true) {
				int num = is.read(data);//읽어온 수 리턴~
				if(num == -1) break;

				for(int i=0; i<num; i++) {
					System.out.println(data[i]);
				}
				for(byte b : data) {//무조건 100번돈다
					System.out.println(b);
				}
			}

			is.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

 

 

InputStream을 가지고 가장 빠르게 보낼때 transferTo()를 사용하는 것이 더 좋다. 

String originalFileName = "C:/Temp/test.jpg";
String targetFileName = "C:/Temp/test2.jpg";

InputStream is = new FileInputStream(originalFileName);
OutputStream os = new FileOutputStream(targetFileName);

is.transferTo(os);//8k로 보냄 InputStream으로 보낼때 가장빠르게 보낼수 있다 아래와 같은 코드

byte[] data = new byte[4*1024];//하드디스크의 파일 크기 관리 크기
while(true) {
    int num = is.read(data);
    if(num == -1) break;
    os.write(data, 0, num);
}

os.flush();
os.close();
is.close();

System.out.println("복사가 잘 되었습니다.");

 

 

8k를 기반으로 내부적으로 그냥 코드랑 read()쓰는 코드와 동일하게 동작한다.

public long transferTo(OutputStream out) throws IOException {
    Objects.requireNonNull(out, "out");
    long transferred = 0;
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    int read;
    while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
        out.write(buffer, 0, read);
        transferred += read;
    }
    return transferred;
}

 

문자 변환 스트림

문자 셋의 종류를 지정할 수있다.

public static String read() throws Exception {
    InputStream is = new FileInputStream("C:/Temp/test.txt");
    Reader reader = new InputStreamReader(is, "UTF-8");
    char[] data = new char[100];//read에는 string이 없기때무에 int변환후 사용
    int num = reader.read(data);
    reader.close();
    String str = new String(data, 0, num);
    return str;
}

 

성능 향상 스트림

HDD에서 문자 데이터를 가져다 쓰려면 시간이 오래 걸린다.  그래서 메모리에 버퍼를 놓고 한번에 받아온다음 처리 스트림으로 하나씩 넘겨준다. HDD보다는 메모리가 더 빠르기 때문에 성능이 좋아진다.

 

 

기본타입 스트림

String으로 받기 넘겨주기

writeUTF()

readUTF()

int로 받기 넘겨주기

writeInt()

readInt()

 

프린트 스트림

print(),println(),printf()를 파일로 출력되도록 쓸수 있는 스트림이다.

 

 

 

 

 

보조스트림

OutputStream os = new FileOutputStream("C:/Temp/test.txt");
byte data [] = str.getBytes();
os.write(data);
os.close();//보조스트림을 안쓴것

Writer writer = new OutputStreamWriter(os, "UTF-8");
writer.write(str);
writer.flush();
writer.close();

 

객체스트림

객체를 출력하려면 필드값을일렬로 늘어선 바이트로 변경해야하는데 이것을 직렬화라고 한다. 반대로 직렬화된 객체의 필드값을 다시 객체로 변경하는 것을 역직렬화라고한다.

writeObject() 객체를 넣을 수있음

readObject() 객체를 읽어 올수 있음

ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("C:/Temp/object.dat")));
		
//객체 생성
Member m1 = new Member("fall", "단풍이");
Product p1 = new Product("노트북", 1500000);
int[] arr1 = { 1, 2, 3 };

//객체를 역직렬화해서 파일에 저장
oos.writeObject(m1);//객체 넘기는건 이 함수 하나면 돼 와우~
oos.writeObject(p1);
oos.writeObject(arr1);

oos.flush();
oos.close(); /* fos.close(); */

//FileInputStream에 ObjectInputStream 보조 스트림 연결
FileInputStream fis = new FileInputStream("C:/Temp/object.dat");
ObjectInputStream ois = new ObjectInputStream(fis);

//파일을 읽고 역질렬화해서 객체로 복원
Member m2 = (Member) ois.readObject();
Product p2 = (Product) ois.readObject();
int[] arr2 = (int[]) ois.readObject();

ois.close(); fis.close();

serializable 인터페이스

면접질문

직렬화 - 객체 상태를 한번에 파일에 저장해준다. 객체상태 그대로를 복원할 수 있다. 저장하고 싶지 않은 정보는 transient를 지정해주면 파일에 저장하지 못하게 설정할수있습니다.

transient 지정할 목록: 패스워드, 주민번호, 윈도우 핸들, 네트워크 핸들, 파일핸들, 데이터베이스 연결은 저장하는게 아니다.

직렬화를 하기 위해 클래스에 상속해주는 인터페이스 이다. transient를 지정해주면 직렬화에서 예민한 정보는 직렬화를 하지 않아서 보안에 좋다.

 

serialVersionUID 필드

직렬화 할 때 사용된 클래스와 역직렬화 할때 사용된 클래스는 기본적으로 동일한 클래스여야 한다 이때 같은 클래스인지 비교할때 쓰는 상수값이다.

 

file

폴더 생성

mkdir()

mkdirs() - mkdir보다는 늦지만 경로가 불확실하다면 이걸로 써서 경로내의 폴더들을 생성해주는 것이 좋다

파일 생성

createNewFile()

파일이나 디렉토리 삭제

delete()

파일명 String으로 가져오기

list()

파일들 file객체로 가져오기

listFiles()

 

디렉토리인지 확인

isDirectory()

 

파일경로 얻어오기

getPath()

파일 이름 얻어오기

getName()

 

files클래스

file의 클래스로 불편하게 쓰던걸 함수한번에 편안하게 쓸수 있음

 

 

네트워크 

여러컴퓨터들을 통신회선으로 연결한 것을 말한다.

 

서버와 클라이언트

서버는 서비스를 제공하는 프로그램이다

클라이언트는 서비스를 요청하는 프로그램이다.

 

IP주소

IP주소는 LAN카드마다 할당된다. 

 

DNS

도메인이름으로 IP주소를 가져오는 저장소이다.

 

IP주소 얻기

InetAddress ia = InetAddress.getLocalHost()

내 IP Address를 갖는 객체를 반환한다.

 

getByName()메소드는 DNS에서 돔인 이르으로 등록된 단하나의 IP주소를 가져온다.

getAllByName()은 메소드에 등록된 모든 IP주소를 배열로 가져온다.

 

getHostAddress()는 본인의 IP주소를 String으로 반환한다.

 

TCP

클라이언트가 연결 요청을 하고 서버가 연결을 수락하면 통신 회선이 고정되고, 데이터는 고정 회선을 통해 전달된다. ServerSocket은 클라이언트의 연결을 수락하는 서버쪽 클래스이고, Socket은 클라이언트에서 연결 요청할때와 클라이언트와 서버 양쪽에서 데이터를 주고 받을때 사용하는 클래스이다. 클라이언트가 소켓을 생성해서 서버에 연결요청을하면 서버는 연결을 수락함과 동시에 해당 클라이언트와만 연결되는 소켓을 생성해서 통신을 시작한다.

 

 

TCP 소켓 프로그램

서버를 돌리고 클라이언트가 서버의 IP주소로 접속해서 사용하는 프로그램 구조

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'JAVA공부(이것이 자바다)' 카테고리의 다른 글

스트림  (2) 2023.06.13
컬렉션 자료구조  (0) 2023.06.12
스레드  (3) 2023.06.09
java.base 이어서  (0) 2023.06.08
java.base 모듈  (2) 2023.06.07