본문 바로가기

개발기술/Java

Java 코딩구현 - I/O System

입력과 출력 (I/O) : 전체 구조

데이터가 하나의 어플리케이션에서 다른 매체로 전송될 때 반드시 Byte Serialization이라는 것을 거쳐야한다. 그리고 수산하는 매체는 이 데이터의 meta 데이터를 활용하여 Deserialization을 통해서 사용가능한 데이터로 변환하는 과정이 필요하다. 

 

    

 

 

  In Java, the input/output (I/O) system is a crucial part of programming that deals with reading data from and writing data to different sources like files, networks, or other external devices.

Streams

Streams are at the core of Java's I/O system. They are used to sequentially read or write data. There are two main types of streams:

  • Byte Streams: Handle I/O of raw binary data.
  • Character Streams: Handle I/O of character data, automatically handling character encoding and decoding.

Byte Streams

  • InputStream / OutputStream: Base classes for reading and writing byte data.
    • FileInputStream and FileOutputStream are for reading and writing data to files.
    • BufferedInputStream and BufferedOutputStream add a buffer to reduce the number of I/O operations required.

Character Streams

  • Reader / Writer: Base classes for reading and writing character data.
    • FileReader and FileWriter are specialized for file I/O.
    • BufferedReader and BufferedWriter include methods for efficient reading and writing of text, such as reading lines of text with readLine().

 

 

 

 

java.nio.file.Files and Path

과거 FILE I/O의 복잡성을 해결하기 위해서 도입한 nio package. Path객체와 Files의 method로 파일의 내용을 모두 읽을 수 있다.

import java.nio.file .*;
import java.io.IOException;
import java.util.List;

    public class FileInputExample {
        public static void main(String[] args) throws IOException {
            // Use Path and Files to read the file
            Path filePath = Paths.get("input.txt");

            // Read all lines at once into a List
            List<String> lines = Files.readAllLines(filePath);

            // Process the file line by line
            lines.forEach(System.out::println);
        }
    }

입력과 출력 (I/O) : 파일시스템

  • File: Represents file and directory pathnames in an abstract, system-independent manner. This does not create or open the file itself; it simply creates an object that Java can use to manipulate a file. 실제로 파일을 생성하는 것이 아니라, 파일이라는 대상을 해당 주소에 추상적으로 만들어내는 객체. 실제로 파일을 생성하지는 않음.
    • Key Methods:
      • exists(): Returns true if the file or directory exists.
      • createNewFile(): Creates a new, empty file if it does not exist.
      • mkdir(), mkdirs(): Creates a directory or series of directories.
      • delete(): Deletes a file or directory.
      • isFile(), isDirectory(): Checks whether the path is a file or a directory.
      • listFiles(): Returns an array of abstract pathnames denoting the files in the directory.
  •   FileWriter:  Used for writing character data to a file. If the file specified in the FileWriter constructor does not exist, it will be created automatically.   is often wrapped in higher-level classes like BufferedWriter to improve performance through buffering.
    • IOException needs to be handled because file operations can fail for various reasons (like the file does not exist).
    • Key Methods:
      • Constructors: FileWriter(String fileName), FileWriter(File file, boolean append).
      • write(): Writes text into the file.
  • BufferedReader / BufferedWriter: The BufferedWriter/reader in Java is specifically designed to wrap around any object that extends the abstract Writer/reader class, thereby providing improved efficiency through buffering. 
    • ex ) BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); bw.write("Hello, world!"); bw.close();
    • 버퍼를 마지막에 close를 해야 stream이 flush가되어 저장매체에 저장된다.
    • Constructors : BufferedReader(Reader in, int sz) for custom buffer sizes / BufferedWriter(Writer out, int sz) for custom buffer sizes.
      • The constructors for BufferedReader and BufferedWriter in Java are designed to wrap around other reader and writer objects, respectively.  
  • StringBuilder: 문자열을 자주 추가하거나 변경할때 사용하는 자료형. DS관점에서 Dynamic Array와 유사하며 기능적으로 StringBuilder와 거의 동일하다. 쓰레드 안정성에서 Single Thread에서는 StringBuilder, Multi Thread에서는 StringBuffer을 사용한다. Builder는 Ram에서 메모리를 충분히 할당받으나 buffer은 ram에서 8000char 가량밖에 할당되지 않고 꽉 찰시 flush를 통해 file로 저장한다.  stringbuffer은 크키는 한정되지 않으나 synchronization을 위해 lock이 구현되어 있어 비교적 비효율적이다.
    • StringBuilder variable = new StringBuilder("text")
    • method
      • append(str,char): Appends the specified string to this character sequence.
        • string에서 a+b로도 concatnation이 가능하지만 string buffer은 dynamic하게 크기가 변하기 때문에 static한 string에 비해서 메모리 비효율적이다.
      • insert(index, String str): Inserts the specified string into this character sequence.
      • delete(strindex, endindex) : Removes the characters substring that begins at the specified start and to at index end - 1
      • reverse() : Reverses the characters within the StringBuffer.
      • setLength() - Sets or adjusts the length of the character sequence. If the new length is shorter, the sequence is truncated; if longer, it is padded with null characters ('\u0000').
      • toString() : Converts Stringbuilder to String
      • String과 공용메서드 : charat(index), substringsubstring(int beginIndex, int endIndex), 
 

 

 

 

 

 

입력과 출력 (I/O) : 입력

The java.io package is part of Java's original I/O API and provides classes for system input and output through data streams, serialization, and the file system.

  • 1. System.in.read() : this method reads raw byte data from the standard input stream (System.in), which typically means it reads one character at a time from the user's keyboard input.
  • 2. InputStreamReader : 개발자의 편의성을 위해서 데이터를 한번에 1바이트씩 읽어들이도록 정의한 도구. 
  • 3. BufferedReader : Ram에서 buffer memory를 할당받아서, inputstream을 통해 들어오는 데이터를 쌓아나가는 곳. bufferedreader와 inputstreamreader가 같이 쓰일때는 1바이트씩이 아니라 bulk로 데이터가 들어온다.
    • 생성 : BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      • readLine(): Reads a line of text. A line is considered to be terminated by any one of a line feed
      • close(): Closes the stream and releases any system resources associated with it.
      • hasMoreTokens(): Tests if there are more tokens available from this tokenizer's string.
  • 4. Stringbuilder : bufferedreader에서 readline으로 받아들인 값은 stringbuilder에 계속 해서 append된다. 이는, string은 고정된 사이즈의 개체인 반면 stringbuilder는 유동적인 사이즈의 배열로 새로 제3의 string을 계속 만들지 않아도 되기때문이다.
  •  StringTokenizer(String str, String delimiter(option), boolean returnDelims(option)) : is used to break a string into tokens as the String.split() but faster performance.  the default delimiters : whitespace characters (spaces, tabs, new lines, etc.). If returnDelims is true, then the delimiters themselves will also be returned as tokens.
    • 생성 : StringTokenizer tokenizer = new StringTokenizer(parameters);
    • nextToken(): Returns the next token from this string tokenizer.
    • hasMoreTokens(): Tests if there are more tokens available from this tokenizer's string.
  • Stringtokenizer와 BufferReader 사용예시

 

 

    •  *Scanner sc = new Scanner(System.in)
      • S`System.in` 을 통해서 사용자의 입력이나 다소 복잡하기에 `Scanner` 라는 클래스를 주로 사용한다.
      • Scanner Method
        • scanner.nextLine()엔터( `\n` )을 입력할 때 까지 문자를 가져온다.
        • nextInt(), nextDouble(), nextFloat(), etc.: to read and convert the next token of the input into a specific type (int, double, float, etc.)..
        • next() : Finds and returns the next complete token that's delimited by space.
        • hasNextLine(), hasNextInt(), hasNextDouble()`: Checks if there is another line, int, double, etc., to read and return true useful for loop or if statement
        • close() : Closes the scanner and releases any resources associated with it
          • Scanner method 중 nextint는 입력값 (ex: 5\n) 중 숫자만 취득하고 나머지 \n을 버퍼메모리에 두기 때문에 nextLine을 실행하여 \n 값을 처리해주어야한다.
      • File file = new File("filename") : 파일 인스턴스를 생성후 scanner의 매개변수로 입력하면 파일의 내용이 system input으로 입력됨.

입력과 출력 (I/O) : 출력

  • `System.out.println()` : 값과 한줄 띄우기를 콘솔에 출력하는 기능이다.
    • java는 문자열과 더해지는 다른 데이터형을 자동적으로 string으로 conversion되기 때문에 System.out.println("a + b = " + sum); 의 표현이 가능함. 반면 python은 자동변환이 되지 않아서 다음과 같이 변환이 필요함. print("a + b = " + str(sum)) or print(f"a + b = {sum}")
  • `System.out.print()` : 한줄 띄우기없이(n : 한줄띄우기), 값을 콘솔에 출력하는 기능이다.
  • BufferWriter : BufferedWriter is a class used to write text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings. Throw Exception 처리를 반드시 해주어야함.
    • ex : BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
    • write(String s, int off, int len): Writes a portion of a string.
    • newLine(): Adds a line separator. The line separator string is defined by the system property line.separator, which is not necessarily a newline (\n) character.
    • flush(): Flushes the buffer, which forces any characters buffered by the BufferedWriter to be written to the underlying output.
    • close(): Closes the writer, but first flushes it one last time to ensure all data in the buffer is written out. After closing, the writer can no longer be used.