Java.io 패키지에는 입력 및 출력을 작동하는 데 필요한 거의 모든 클래스가 포함되어 있습니다. 이러한 모든 스트림 클래스는 입력 소스와 출력 대상을 나타냅니다.
Java.io 패키지의 스트림은 기본 유형, 객체, 지역화된 문자 집합 등과 같은 다양한 형식을 지원합니다.
스트림은 데이터의 시퀀스로 이해될 수 있습니다. 입력 스트림은 소스에서 데이터를 읽는 것을 나타내고, 출력 스트림은 대상에 데이터를 쓰는 것을 나타냅니다.
Java는 I/O에 대한 강력하고 유연한 지원을 제공하므로 파일 전송 및 네트워크 프로그래밍에 더욱 널리 사용됩니다.
하지만 이 섹션에서는 스트림 및 I/O와 관련된 가장 기본적인 기능을 다룹니다. 이러한 기능을 하나씩 예제를 통해 배워보겠습니다.
Java의 콘솔 입력은 System.in에 의해 수행됩니다.
콘솔에 바인딩된 문자 스트림을 얻으려면 System.in을 BufferedReader 개체로 래핑하여 문자 스트림을 만들 수 있습니다.
다음은 BufferedReader를 생성하기 위한 기본 구문입니다.
BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in));
BufferedReader 객체가 생성된 후 read() 메서드를 사용하여 콘솔에서 문자를 읽거나 readLine() 메서드를 사용하여 문자열을 읽을 수 있습니다.
BufferedReader 객체에서 문자를 읽으려면 read() 메서드를 사용합니다. 해당 구문은 다음과 같습니다.
intread()throwsIOException
read() 메서드가 호출될 때마다 입력 스트림에서 문자를 읽고 해당 문자를 정수 값으로 반환합니다. 스트림이 끝나면 -1을 반환합니다. 이 메소드는 IOException을 발생시킵니다.
다음 프로그램은 read() 메서드를 사용하여 사용자가 "q"를 입력할 때까지 콘솔에서 문자를 계속 읽는 방법을 보여줍니다.
//使用BufferedReader在控制台读取字符importjava.io.*; publicclassBRRead{ publicstaticvoidmain(Stringargs[])throwsIOException { charc; //使用System.in创建BufferedReader BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in)); System.out.println("输入字符, 按下'q' 键退出."); //读取字符do{ c=(char)br.read(); System.out.println(c); }while(c!='q'); } }
위 예제의 컴파일 및 실행 결과는 다음과 같습니다.
输入字符, 按下'q' 键退出. 123abcq 1 2 3 a b c q
표준 입력에서 문자열을 읽으려면 BufferedReader의 readLine() 메서드를 사용해야 합니다.
일반적인 형식은 다음과 같습니다.
StringreadLine()throwsIOException
다음 프로그램은 "end"라는 단어를 입력할 때까지 문자 줄을 읽고 표시합니다.
//使用BufferedReader在控制台读取字符importjava.io.*; publicclassBRReadLines{ publicstaticvoidmain(Stringargs[])throwsIOException { //使用System.in创建BufferedReader BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in)); Stringstr; System.out.println("Enterlinesoftext."); System.out.println("Enter'end'toquit."); do{ str=br.readLine(); System.out.println(str); }while(!str.equals("end")); } }
위 예제의 컴파일 및 실행 결과는 다음과 같습니다.
Enterlinesoftext. Enter'end'toquit. Thisislineone Thisislineone Thisislinetwo Thisislinetwo end end
앞에서 언급했듯이 콘솔 출력은 print() 및 println()에 의해 완료됩니다. 이러한 메서드는 PrintStream 클래스에 의해 정의되며 System.out은 이 클래스의 개체에 대한 참조입니다.
PrintStream은 OutputStream 클래스를 상속하고 write() 메서드를 구현합니다. 이러한 방식으로 write()를 사용하여 콘솔에 작업을 쓸 수도 있습니다.
PrintStream은 다음과 같이 가장 간단한 형식으로 write()를 정의합니다.
voidwrite(intbyteval)
이 메서드는 byteval의 하위 옥텟을 스트림에 씁니다.
다음 예에서는 write()를 사용하여 문자 "A"와 개행 문자를 화면에 인쇄합니다.
importjava.io.*; //演示System.out.write(). publicclassWriteDemo{ publicstaticvoidmain(Stringargs[]){ intb; b='A'; System.out.write(b); System.out.write('n'); } }
위의 예제를 실행하여 출력 창에 "A" 문자를 출력합니다.
A
참고: write() 메서드는 print() 및 println() 메서드가 사용하기 더 편리하기 때문에 자주 사용되지 않습니다.
앞서 언급했듯이 스트림은 데이터 시퀀스로 정의됩니다. 입력 스트림은 소스에서 데이터를 읽는 데 사용되고, 출력 스트림은 대상에 데이터를 쓰는 데 사용됩니다.
다음 그림은 입력 스트림과 출력 스트림을 설명하는 클래스 계층 다이어그램입니다.
아래에서 설명할 두 가지 중요한 스트림은 FileInputStream과 FileOutputStream입니다.
이 스트림은 파일에서 데이터를 읽는 데 사용되며 해당 객체는 new 키워드를 사용하여 생성될 수 있습니다.
객체를 생성하는 데 사용되는 다양한 생성자 메서드가 있습니다.
문자열 파일 이름을 사용하여 파일을 읽기 위한 입력 스트림 객체를 생성할 수 있습니다.
InputStreamf=newFileInputStream("C:/java/hello");
파일 객체를 사용하여 파일을 읽기 위한 입력 스트림 객체를 생성할 수도 있습니다. 먼저 File() 메소드를 사용하여 파일 객체를 생성해야 합니다:
Filef=newFile("C:/java/hello"); InputStreamf=newFileInputStream(f);
InputStream 객체를 생성한 후 다음 메서드를 사용하여 스트림을 읽거나 다른 스트림 작업을 수행할 수 있습니다.
일련번호 | 방법 및 설명 |
---|---|
1 | public void close() throws IOException{} 이 파일 입력 스트림을 닫고 이 스트림과 관련된 모든 시스템 리소스를 해제합니다. IOException을 발생시킵니다. |
2 | protected void finalize()throws IOException {} 이 메서드는 파일에 대한 연결을 지웁니다. 더 이상 참조되지 않는 파일 입력 스트림의 닫기 메서드를 호출해야 합니다. IOException을 발생시킵니다. |
3 | public int read(int r)throws IOException{} 이 메서드는 InputStream 개체에서 지정된 데이터 바이트를 읽습니다. 정수 값으로 반환됩니다. 데이터의 다음 바이트를 반환하거나 끝에 도달한 경우 -1을 반환합니다. |
4 | public int read(byte[] r) throws IOException{} 이 메서드는 입력 스트림에서 r.length 바이트를 읽습니다. 읽은 바이트 수를 반환합니다. 파일의 끝이면 -1이 반환됩니다. |
5 | public int available() throws IOException{} 이 입력 스트림에서 다음 메서드 호출에 의해 차단되지 않고 이 입력 스트림에서 읽을 수 있는 바이트 수를 반환합니다. 정수 값을 반환합니다. |
InputStream 외에도 다른 입력 스트림이 있습니다. 자세한 내용은 아래 링크를 참조하세요.
ByteArrayInputStream
데이터입력스트림
이 클래스는 파일을 생성하고 파일에 데이터를 쓰는 데 사용됩니다.
스트림이 출력용 파일을 열기 전에 대상 파일이 존재하지 않으면 스트림은 파일을 생성합니다.
FileOutputStream 개체를 만드는 데 사용할 수 있는 생성자는 두 가지가 있습니다.
문자열 파일 이름을 사용하여 출력 스트림 개체를 만듭니다.
OutputStreamf=newFileOutputStream("C:/java/hello")
파일 객체를 사용하여 파일에 쓸 출력 스트림을 생성할 수도 있습니다. 먼저 File() 메소드를 사용하여 파일 객체를 생성해야 합니다:
Filef=newFile("C:/java/hello"); OutputStreamf=newFileOutputStream(f);
OutputStream 객체를 생성한 후 다음 메서드를 사용하여 스트림에 쓰거나 다른 스트림 작업을 수행할 수 있습니다.
일련번호 | 방법 및 설명 |
---|---|
1 | public void close() throws IOException{} 이 파일 입력 스트림을 닫고 이 스트림과 관련된 모든 시스템 리소스를 해제합니다. IOException을 발생시킵니다. |
2 | protected void finalize()throws IOException {} 이 메서드는 파일에 대한 연결을 지웁니다. 더 이상 참조되지 않는 파일 입력 스트림의 닫기 메서드를 호출해야 합니다. IOException을 발생시킵니다. |
3 | public void write(int w)throws IOException{} 이 메서드는 지정된 바이트를 출력 스트림에 씁니다. |
4 | public void write(byte[] w)는 지정된 배열에서 길이가 w.length인 바이트를 OutputStream에 씁니다. |
OutputStream 외에도 다른 출력 스트림이 있습니다. 자세한 내용은 아래 링크를 참조하세요.
ByteArrayOutputStream
데이터출력스트림
다음은 InputStream 및 OutputStream의 사용법을 보여주는 예입니다.
import java.io.*; public class fileStreamTest { public static void main(String args[]) { try { byte bWrite[] = { 11, 21, 3, 40, 5 }; OutputStream os = new FileOutputStream("test.txt"); for (int x = 0; x < bWrite.length; x++) { os.write(bWrite[x]); // writes the bytes } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for (int i = 0; i < size; i++) { System.out.print((char) is.read() + " "); } is.close(); } catch (IOException e) { System.out.print("Exception"); } } }
위 프로그램은 먼저 test.txt 파일을 생성하고, 주어진 숫자를 바이너리 형식으로 파일에 쓴 후 콘솔에 출력합니다.
위의 코드는 바이너리로 작성되었기 때문에 문자가 깨졌을 수 있습니다. 다음 코드 예제를 사용하여 깨진 코드 문제를 해결할 수 있습니다.
//文件名:fileStreamTest2.java importjava.io.*; publicclassfileStreamTest2{ publicstaticvoidmain(String[]args)throwsIOException{ Filef=newFile("a.txt"); FileOutputStreamfop=newFileOutputStream(f); //构建FileOutputStream对象,文件不存在会自动新建OutputStreamWriterwriter=newOutputStreamWriter(fop,"UTF-8"); //构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk writer.append("中文输入"); //写入到缓冲区writer.append("rn"); //换行writer.append("English"); //刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入writer.close(); //关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉fop.close(); //关闭输出流,释放系统资源 FileInputStreamfip=newFileInputStream(f); //构建FileInputStream对象InputStreamReaderreader=newInputStreamReader(fip,"UTF-8"); //构建InputStreamReader对象,编码与写入相同 StringBuffersb=newStringBuffer(); while(reader.ready()){ sb.append((char)reader.read()); //转成char加到StringBuffer对象中 } System.out.println(sb.toString()); reader.close(); //关闭读取流fip.close(); //关闭输入流,释放系统资源 } }
또한 우리가 알아야 할 파일 및 I/O에 대한 몇 가지 클래스도 있습니다.
파일 클래스(class)
FileReader 클래스(클래스)
FileWriter 클래스(클래스)
File 클래스에는 폴더를 만드는 데 사용할 수 있는 두 가지 메서드가 있습니다.
mkdir() 메소드는 폴더를 생성하고 성공하면 true를, 실패하면 false를 반환합니다. 실패는 File 객체에 지정된 경로가 이미 존재하거나 전체 경로가 아직 존재하지 않기 때문에 폴더를 생성할 수 없음을 나타냅니다.
mkdirs() 메서드는 폴더와 모든 상위 폴더를 생성합니다.
다음 예에서는 "/tmp/user/java/bin" 폴더를 만듭니다.
importjava.io.File; publicclassCreateDir{ publicstaticvoidmain(Stringargs[]){ Stringdirname="/tmp/user/java/bin"; Filed=newFile(dirname); //现在创建目录d.mkdirs(); } }
위 코드를 컴파일하고 실행하여 "/tmp/user/java/bin" 디렉터리를 만듭니다.
참고: Java는 UNIX 및 Windows의 규칙에 따라 파일 경로 구분 기호를 자동으로 확인합니다. Windows 버전의 Java에서 구분 기호(/)를 사용하면 경로가 여전히 올바르게 구문 분석됩니다.
디렉터리는 실제로 다른 파일과 폴더를 포함하는 File 객체입니다.
File 객체를 생성하고 이것이 디렉토리인 경우 isDirectory() 메서드를 호출하면 true가 반환됩니다.
객체에 대해 list() 메서드를 호출하여 포함된 파일 및 폴더 목록을 추출할 수 있습니다.
아래 예에서는 list() 메서드를 사용하여 폴더 내용을 확인하는 방법을 보여줍니다.
importjava.io.File; publicclassDirList{ publicstaticvoidmain(Stringargs[]){ Stringdirname="/tmp"; Filef1=newFile(dirname); if(f1.isDirectory()){ System.out.println("Directoryof"+dirname); Strings[]=f1.list(); for(inti=0;i<s.length;i++){ Filef=newFile(dirname+"/"+s[i]); if(f.isDirectory()){ System.out.println(s[i]+"是一个目录"); }else{ System.out.println(s[i]+"是一个文件"); } } }else{ System.out.println(dirname+"不是一个目录");
} } }
위 예제의 컴파일 및 실행 결과는 다음과 같습니다.
目录/tmp bin 是一个目录lib 是一个目录demo 是一个目录test.txt 是一个文件README 是一个文件index.html 是一个文件include 是一个目录
파일을 삭제하려면 java.io.File.delete() 메서드를 사용하세요.
다음 코드는 /tmp/java/ 디렉토리를 삭제합니다. 특정 디렉토리를 삭제할 때 디렉토리에 다른 파일이 없는지 확인해야 올바르게 삭제됩니다.
테스트 디렉토리 구조:
/tmp/자바/ |-- 1.로그 |-- 테스트
import java.io.File; public class DeleteFileDemo { public static void main(String args[]) { // 这里修改为自己的测试目录File folder = new File("/tmp/java/"); deleteFolder(folder); } // 删除文件及目录public static void deleteFolder(File folder) { File[] files = folder.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { deleteFolder(f); } else { f.delete(); } } } folder.delete(); } }