Java/Java

파일 입출력 (InputStream, OuputStream, FileReader, FileWriter, File)

마손리 2023. 3. 9. 21:57

InputStream, OutputStream

 

자바에서는 입출력을 다루기 위한 InputStream, OutputStream을 제공한다. 스트림은 단방향으로만 데이터를 전송할 수 있기에, 입력과 출력을 동시에 처리하기 위해서는 각각의 스트림이 필요하다.

입출력 스트림은 어떤 대상을 다루느냐에 따라 종류가 나뉜다. 예를 들면, File을 다룰 때는 FileInputStream / FileOutputStream을 사용하고, 프로세스를 다룰 때는 PipedInputStream / PipedOutputStream을 사용한다.

FileInputStream

echo code >> helloWorld.txt

아무 파일이나 생성,

이후 FileInputStream으로 파일의 내용을 읽을수 있다.

import java.io.FileInputStream;
  
public class FileInputStreamExample {
    public static void main(String args[])
    {
        try {
            FileInputStream fileInput = new FileInputStream("helloWorld.txt");
            int i = 0;
            while ((i = fileInput.read()) != -1) { 
            //fileInput.read()의 리턴값을 i에 저장한 후, 값이 -1인지 확인한다. 
            //더이상 확인할 데이터가없으면 read()메서드는 -1을 리턴하며 FileReader도 동일
                System.out.print((char)i);
            }//FileInputStream과 FileOutputStream은 바이트기반 스트림으로 위처럼 바이트단위로 접근해야한다.
            
            fileInput.close();
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }
}

BufferedInputStream이라는 보조 스트림을 사용하면 성능이 향상되기 때문에, 대부분의 경우 이를 사용한다. 버퍼란 바이트 배열로서, 여러 바이트를 저장하여 한 번에 많은 양의 데이터를 입출력할 수 있도록 도와주는 임시 저장 공간이다.

 

import java.io.FileInputStream;
import java.io.BufferedInputStream;
  
public class FileInputStreamExample {
    public static void main(String args[])
    {
        try {
            FileInputStream fileInput = new FileInputStream("helloWorld.txt");
	    BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);
            int i = 0;
            while ((i = bufferedInput.read()) != -1) {
                System.out.print((char)i);
            }
            fileInput.close();
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }
}

보조 스트림도 스트림의 하위 클래스이기 때문에 입출력방법은 같음.

FileOutputStream

import java.io.FileOutputStream;
  
public class FileOutputStreamExample {
    public static void main(String args[]) {
        try {
            FileOutputStream fileOutput = new FileOutputStream("helloWorld.txt");
            BufferedOutputStream  bufferedOutputStream = new BufferedOutputStream(fileOutput);
            String word = "code";

            byte b[] = word.getBytes(); //마찬가지로 바이트단위
            bufferedOutputStream.write(b);
            bufferedOutputStream.close();
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }
}

위 코드를 실행하면, 같은 디렉토리 내에 code라는 문자열이 입력된 helloWord.txt 파일이 생성

 

 

FileReader / FileWriter

 

앞서 살펴본 File 입출력 스트림은, 바이트 기반 스트림이다. 바이트 기반은 입출력 단위가 1byte라는 뜻입니다.하지만 Java에서 char 타입은 2byte(자바 기본 유닛 참고)이며 이를 해소하기 위해 자바에서는 문자 기반 스트림을 제공한다. 문자 기반 스트림에는 FileReader와 FileWriter가 있다.

문자 기반 스트림은 문자 데이터를 다룰 때 사용한다.

문자 기반 스트림과 그 하위 클래스는 여러 종류의 인코딩(encoding)과 자바에서 사용하는 유니코드(UTF-16)간의 변환을 자동으로 처리한다.

 

문자 기반 스트림에서는 일반적으로, 바이트 기반 스트림의 InputStream이 Reader로, OutputStream이 Writer로 대응된된다. (FileInputStream이 문자 기반에서는 FileReader에, FileOutputStream은 FileWriter에 해당하는 식)

 

FileReader는 인코딩을 유니코드로 변환하고, FileWriter는 유니코드를 인코딩으로 변환한다.

 

FileReader와 BufferedReader

바이트 기반 스트림과 마찬가지로, Reader에도 성능을 개선할 수 있는 BufferedReader가 있다.

public class BufferedReaderExample {
    public static void main(String args[]) {
        try {
            String fileName = "helloWorld.txt";
            FileReader file = new FileReader(fileName);
            BufferedReader buffered = new BufferedReader(file);

            int data = 0;

            while((data=buffered.read()) != -1) {//FileInputStream과 마찬가지로 데이터가 없으면 -1리턴
                System.out.print((char)data);
            }
            file.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FileWriter와 BufferedWriter

public class FileWriterExample {
    public static void main(String args[]) {
        try {
            String fileName = "helloWorld.txt";
            FileWriter writer = new FileWriter(fileName);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            
            String str = "written!";
            bufferedWriter.write(str);
            bufferedWriter.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

위 코드로 인해 helloWorld.txt파일의 내용이 바뀌었으며 만약 해당 파일이 없을시 자동생성된다.

 

File

자바에서는 File 클래스로 파일과 디렉토리에 접근할 수 있다.

import java.io.*;

public class FileExample {
    public static void main(String args[]) throws IOException {
            File file = new File("../helloWorld.txt");
            //File file = new File("./", "helloWorld.txt"); 위와 동일
	    
            file.createNewFile();
            //위의 객체가 생성할때의 경로와 파일명으로 빈 파일을 생성하며 아래의 canWrite()메서드의
            //수정 권한을 true로 바꿔준다. 이미 존재하는 파일이라도 안의 내용은 보존되며 권한만 true로 바뀐다.


            System.out.println(file.getPath());//현재폴더경로 (상대경로)
            System.out.println(file.getParent());//부모폴더경로 (상대경로)
            System.out.println(file.getCanonicalPath());//루트부터의 절대경로
            System.out.println(file.canWrite());
            //파일이 수정가능한지 boolean으로 알려준다.(솔직히 어떤의미에서의 수정인지 잘모르겠다...)
            //처음 기본값은 false이며 위의 createNewFile()메서드를 거치면 true로바뀐다.
          
    }
}

 

renameTo()메서드를 이용하여 파일명을 변경해줄수 있으며 특정 경로를 지정하여 파일의 "이동" 또한 가능하다.

import java.io.File;

public class FileClassExample {
    public static void main(String[] args) {

        File parentDir = new File("./");
        File[] list = parentDir.listFiles();//위의 경로의 모든 파일들을 배열에 모음

        String prefix = "coding";

        for(int i =0; i <list.length; i++) {
            String fileName = list[i].getName();

		if(fileName.endsWith("txt") && !fileName.startsWith("code")) {
                list[i].renameTo(new File(parentDir, prefix + fileName));
            }	//renameTo메서드를 이용, 파일경로와 새로운이름으로 파일의 이름을 바꿔줄수있다.
            
/*            if(fileName.endsWith("txt")) {
                list[i].renameTo(new File(parentDir+"/src/", fileName));
            }renameTo를 활용하여 파일들의 "이동"도 가능하다.  */
        }
    }
}
 

 

'Java > Java' 카테고리의 다른 글

스트림의 메서드  (2) 2023.03.11
스트림 (Stream)  (0) 2023.03.10
람다(Lambda)  (2) 2023.03.09
컬렉션 프레임워크 (Collection Framework)  (0) 2023.03.08
try(), catch() - 예외 처리(Exception Handling)  (0) 2023.03.07