파일 을 쓰 는 6 가지 방법 중 성능 이 가장 좋다.
14611 단어 자바
본 격 적 으로 시작 하기 전에 우 리 는 먼저 몇 가지 기본 적 인 개념 인 흐름, 바이트 흐름 과 문자 흐름 의 정의 와 차 이 를 알 아 보 자.
0. 무엇이 흐름 입 니까?
자바 의 '흐름' 은 추상 적 인 개념 이자 비유 이다. 마치 물 흐름 처럼 물 흐름 은 한 끝 에서 다른 한 끝 으로 흐 르 고 자바 에서 의 '흐름' 은 바로 데이터 이 며 데 이 터 는 한 끝 에서 '흐름' 다른 한 끝 으로 흐른다.
흐름 의 방향 성에 따라 우 리 는 흐름 을 입력 흐름 과 출력 흐름 으로 나 눌 수 있 습 니 다. 프로그램 이 데이터 원본 에서 데 이 터 를 읽 어야 할 때 입력 흐름 이 열 립 니 다. 반대로 데 이 터 를 특정한 데이터 원본 목적지 에 쓸 때 도 출력 흐름 이 열 립 니 다. 데이터 원본 은 파일, 메모리 또는 네트워크 등 이 될 수 있 습 니 다.
1. 바이트 흐름 이란 무엇 인가?
바이트 흐름 의 기본 단 위 는 바이트 (Byte) 이 고 한 바이트 는 보통 8 자리 이 며 바 이 너 리 (데이터) 를 처리 하 는 데 사용 된다.바이트 흐름 은 두 가지 기본 클래스 가 있 습 니 다.
InputStream
(입력 바이트 흐름) 과 OutputStream
(출력 바이트 흐름).상용 바이트 흐름 의 계승 관계 도 는 다음 그림 과 같다. 그 중에서
InputStream
는 읽 기 동작 에 사용 되 고 OutputStream
는 쓰기 동작 에 사용 된다.2. 문자 흐름 이란 무엇 인가?
문자 흐름 의 기본 단 위 는 유 니 코드 이 고 크기 는 두 바이트 (Byte) 이 며 텍스트 데 이 터 를 처리 하 는 데 사 용 됩 니 다.문자 흐름 의 두 기본 클래스:
Reader
(입력 문자 흐름) 과 Writer
(출력 문자 흐름).상용 문자 흐름 의 계승 관계 도 는 다음 그림 과 같다.
3. 흐름 의 분류
흐름 은 서로 다른 차원 에 따라 분류 할 수 있다. 예 를 들 어 흐름 의 방향 에 따라 분류 할 수도 있 고 전송 하 는 단위 에 따라 분류 할 수도 있 으 며 흐름 의 기능 에 따라 분류 할 수도 있다. 예 를 들 어 다음 과 같은 몇 가지 이다.
① 흐름 에 따라 분류
OutputStream
과 Writer
기류 로 삼다.InputStream
과 Reader
을 기본 클래스 로 합 니 다.② 전송 데이터 단위 별 분류
OutputStream
과 InputStream
을 기본 으로 한다.Writer
와 Reader
기류 로 삼다.③ 기능 별 분류
PS: 우 리 는 보통 데 이 터 를 전송 하 는 단위 로 분류 합 니 다.
4. 파일 을 쓰 는 6 가지 방법
파일 을 쓰 는 방법 은 주로 문자 흐름
Writer
에서 비롯 됩 니 다. 출력 바이트 흐름 OutputStream
의 하위 클래스 는 다음 그림 과 같다.이상 표시✅번호 의 클래스 는 파일 기록 을 실현 하 는 클래스 입 니 다. 그 밖 에 JDK 1.7 에서 도 제 공 됩 니 다
Files
. 클래스 는 파일 에 대한 각종 조작 을 실현 하 는 데 쓰 인 다. 다음은 우리 가 각각 살 펴 보 자.방법 1: FileWriter
FileWriter
'문자 흐름' 시스템 의 일원 이자 파일 기록 의 기본 클래스 입 니 다. 5 개의 구조 함 수 를 포함 하여 구체 적 인 파일 위 치 를 전달 하거나 File
대상, 두 번 째 매개 변 수 는 파일 을 추가 할 지 여 부 를 표시 합 니 다. 기본 값 은 false
파일 내용 을 추가 하 는 것 이 아니 라 파일 내용 을 다시 쓰 는 것 을 표시 합 니 다. (파일 을 추가 하 는 방법 에 대해 서 는 나중에 말씀 드 리 겠 습 니 다.)FileWriter
류 의 실현 은 다음 과 같다./**
* 1: FileWriter
* @param filepath
* @param content
* @throws IOException
*/
public static void fileWriterMethod(String filepath, String content) throws IOException {
try (FileWriter fileWriter = new FileWriter(filepath)) {
fileWriter.append(content);
}
}
구체 적 인 파일 경로 와 기록 할 내용 만 입력 하면 됩 니 다. 호출 코드 는 다음 과 같 습 니 다.
public static void main(String[] args) {
fileWriterMethod("/Users/mac/Downloads/io_test/write1.txt", " ,Java .");
}
그리고 우 리 는 기 록 된 파일 을 열 었 습 니 다. 결 과 는 다음 과 같 습 니 다.
자원 방출 에 관 한 문제: JDK 7 이상 버 전에 서 는 try - with - resource 방식 만 사용 하면 자원 의 방출 을 실현 할 수 있 습 니 다. 예 를 들 어 try (FileWriter fileWriter = new FileWriter (filepath) {...} 을 사용 하면 FileWriter 자원 의 자동 방출 을 실현 할 수 있 습 니 다.
방법 2: Buffered Writer
BufferedWriter
문자 흐름 시스템 의 일원 에 속 합 니 다. FileWriter
다른 것 은 BufferedWriter
자체 버퍼 입 니 다. 따라서 파일 을 쓰 는 성능 이 더 높 습 니 다. (다음 글 은 두 사람 을 테스트 합 니 다)작은 지식 포인트: 버퍼
버퍼 는 캐 시 라 고도 부 르 며 메모리 공간의 일부분 입 니 다.즉, 메모리 공간 에 일정한 저장 공간 을 남 겨 두 었 는데 이런 저장 공간 은 입력 이나 출력 데 이 터 를 버퍼 링 하 는데 이 부분 에 남 겨 진 공간 을 버퍼 라 고 한다.
버퍼 의 장점 은 파일 흐름 의 기록 을 예 로 들 면 버퍼 를 사용 하지 않 으 면 CPU 를 쓸 때마다 저속 저장 장치, 즉 디스크 와 상호작용 을 한다. 그러면 전체 파일 을 쓰 는 속 도 는 저속 저장 장치 (디스크) 에 제약 을 받는다.그러나 버퍼 를 사용 하면 쓰기 동작 을 할 때마다 데 이 터 를 고속 버퍼 메모리 에 저장 하고 버퍼 의 데이터 가 특정한 한도 값 에 도달 한 후에 파일 을 디스크 에 한꺼번에 기록 합 니 다.메모리 의 기록 속도 가 디스크 의 기록 속도 보다 훨씬 크기 때문에 버퍼 가 있 으 면 파일 의 기록 속도 가 크게 향상 된다.
캐 시 구역 의 장점 을 알 게 된 후에 우 리 는 본 고의 주제 로 돌아 갔다. 그 다음 에 우 리 는
BufferedWriter
로 파일 을 기록 하고 코드 는 다음 과 같다./**
* 2: BufferedWriter
* @param filepath
* @param content
* @throws IOException
*/
public static void bufferedWriterMethod(String filepath, String content) throws IOException {
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath))) {
bufferedWriter.write(content);
}
}
호출 코드 는 방법 1 과 유사 하 므 로 여 기 는 더 이상 군말 하지 않 겠 습 니 다.
방법 3: PrintWriter
PrintWriter
또한 문자 흐름 시스템 의 일원 에 속 합 니 다. '문자 인쇄 흐름' 이 라 고 하지만 이 를 사용 하면 파일 의 기록 을 실현 할 수 있 습 니 다. 코드 는 다음 과 같 습 니 다./**
* 3: PrintWriter
* @param filepath
* @param content
* @throws IOException
*/
public static void printWriterMethod(String filepath, String content) throws IOException {
try (PrintWriter printWriter = new PrintWriter(new FileWriter(filepath))) {
printWriter.print(content);
}
}
상기 코드 를 통 해 알 수 있 듯 이
PrintWriter
이 든 BufferedWriter
이 든 모두 FileWriter
를 바탕 으로 해 야 한다. 클래스 로 호출 완료.방법 4: FileOutputStream
위의 세 가지 예 는 문자 흐름 이 파일 에 쓰 이 는 것 에 대한 작업 이 며, 그 다음 에 우 리 는 바이트 흐름 을 사용 하여 파일 기록 을 완성 할 것 입 니 다.우 리 는 사용 할 것 이다
String
자체 적 인 getBytes()
방법 은 문자열 을 바 이 너 리 파일 로 변환 한 다음 에 파일 을 기록 합 니 다. 이 구현 코드 는 다음 과 같 습 니 다./**
* 4: FileOutputStream
* @param filepath
* @param content
* @throws IOException
*/
public static void fileOutputStreamMethod(String filepath, String content) throws IOException {
try (FileOutputStream fileOutputStream = new FileOutputStream(filepath)) {
byte[] bytes = content.getBytes();
fileOutputStream.write(bytes);
}
}
방법 5: BufferedOutputStream
BufferedOutputStream
바이트 흐름 시스템 의 일원 에 속 합 니 다. FileOutputStream
다른 것 은 버퍼 기능 을 가지 고 있 기 때문에 성능 이 더 좋 습 니 다. 실현 코드 는 다음 과 같 습 니 다./**
* 5: BufferedOutputStream
* @param filepath
* @param content
* @throws IOException
*/
public static void bufferedOutputStreamMethod(String filepath, String content) throws IOException {
try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
new FileOutputStream(filepath))) {
bufferedOutputStream.write(content.getBytes());
}
}
방법 6: Files
다음 작업 방법 은 이전 코드 와 다 릅 니 다. 다음은 JDK 7 에서 제공 하 는 새로운 파일 작업 클래스
Files
를 사용 하 겠 습 니 다. 파일 의 기록 을 실현 합 니 다.Files
클래스 는 JDK 7 에 추 가 된 새로운 작업 파일 의 클래스 입 니 다. 파일 복사, 읽 기, 쓰기, 파일 속성 가 져 오기, 파일 디 렉 터 리 바로 옮 기기 등 파일 을 처리 하 는 방법 을 많이 제공 합 니 다. 이 방법 들 은 파일 의 작업 을 편리 하 게 해 줍 니 다. 구현 코드 는 다음 과 같 습 니 다./**
* 6: Files
* @param filepath
* @param content
* @throws IOException
*/
public static void filesTest(String filepath, String content) throws IOException {
Files.write(Paths.get(filepath), content.getBytes());
}
이상 의 이 방법 들 은 모두 파일 의 기록 을 실현 할 수 있 습 니 다. 어떤 방법 이 성능 이 더 좋 습 니까?이제 테스트 해 보 겠 습 니 다.
5. 성능 테스트
우 리 는 먼저 비교적 큰 문자열 을 구축 한 다음 에 상기 6 가지 방법 으로 파일 의 기록 속 도 를 테스트 한 다음 에 결 과 를 인쇄 합 니 다. 테스트 코드 는 다음 과 같 습 니 다.
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
public class WriteExample {
public static void main(String[] args) throws IOException {
//
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
stringBuilder.append("ABCDEFGHIGKLMNOPQRSEUVWXYZ");
}
//
final String content = stringBuilder.toString();
//
final String filepath1 = "/Users/mac/Downloads/io_test/write1.txt";
final String filepath2 = "/Users/mac/Downloads/io_test/write2.txt";
final String filepath3 = "/Users/mac/Downloads/io_test/write3.txt";
final String filepath4 = "/Users/mac/Downloads/io_test/write4.txt";
final String filepath5 = "/Users/mac/Downloads/io_test/write5.txt";
final String filepath6 = "/Users/mac/Downloads/io_test/write6.txt";
// : FileWriter
long stime1 = System.currentTimeMillis();
fileWriterTest(filepath1, content);
long etime1 = System.currentTimeMillis();
System.out.println("FileWriter :" + (etime1 - stime1));
// : BufferedWriter
long stime2 = System.currentTimeMillis();
bufferedWriterTest(filepath2, content);
long etime2 = System.currentTimeMillis();
System.out.println("BufferedWriter :" + (etime2 - stime2));
// : PrintWriter
long stime3 = System.currentTimeMillis();
printWriterTest(filepath3, content);
long etime3 = System.currentTimeMillis();
System.out.println("PrintWriterTest :" + (etime3 - stime3));
// : FileOutputStream
long stime4 = System.currentTimeMillis();
fileOutputStreamTest(filepath4, content);
long etime4 = System.currentTimeMillis();
System.out.println("FileOutputStream :" + (etime4 - stime4));
// : BufferedOutputStream
long stime5 = System.currentTimeMillis();
bufferedOutputStreamTest(filepath5, content);
long etime5 = System.currentTimeMillis();
System.out.println("BufferedOutputStream :" + (etime5 - stime5));
// : Files
long stime6 = System.currentTimeMillis();
filesTest(filepath6, content);
long etime6 = System.currentTimeMillis();
System.out.println("Files :" + (etime6 - stime6));
}
/**
* : Files
* @param filepath
* @param content
* @throws IOException
*/
private static void filesTest(String filepath, String content) throws IOException {
Files.write(Paths.get(filepath), content.getBytes());
}
/**
* : BufferedOutputStream
* @param filepath
* @param content
* @throws IOException
*/
private static void bufferedOutputStreamTest(String filepath, String content) throws IOException {
try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
new FileOutputStream(filepath))) {
bufferedOutputStream.write(content.getBytes());
}
}
/**
* : FileOutputStream
* @param filepath
* @param content
* @throws IOException
*/
private static void fileOutputStreamTest(String filepath, String content) throws IOException {
try (FileOutputStream fileOutputStream = new FileOutputStream(filepath)) {
byte[] bytes = content.getBytes();
fileOutputStream.write(bytes);
}
}
/**
* : PrintWriter
* @param filepath
* @param content
* @throws IOException
*/
private static void printWriterTest(String filepath, String content) throws IOException {
try (PrintWriter printWriter = new PrintWriter(new FileWriter(filepath))) {
printWriter.print(content);
}
}
/**
* : BufferedWriter
* @param filepath
* @param content
* @throws IOException
*/
private static void bufferedWriterTest(String filepath, String content) throws IOException {
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath))) {
bufferedWriter.write(content);
}
}
/**
* : FileWriter
* @param filepath
* @param content
* @throws IOException
*/
private static void fileWriterTest(String filepath, String content) throws IOException {
try (FileWriter fileWriter = new FileWriter(filepath)) {
fileWriter.append(content);
}
}
}
결 과 를 보기 전에 저 희 는 먼저 대응 하 는 폴 더 에 가서 기 록 된 파일 이 정상 적 인지 확인 하 겠 습 니 다. 다음 그림 에서 보 듯 이 문자 흐름 의 조작 속도 가 가장 빠 릅 니 다. 이것 은 저희 가 이번에 테스트 한 코드 가 문자열 이기 때문에 바이트 흐름 을 사용 할 때 문자열 을 바이트 흐름 으로 바 꿔 야 하기 때문에 실행 효율 에 있어 서 우세 하지 않 습 니 다.
이 같은 결 과 를 통 해 알 수 있 듯 이 성능 이 가장 좋 은 것 은 버퍼 가 있 는 문자열 쓰기 흐름
BufferedWriter
이 고 성능 이 가장 느 린 것 은 Files
이다.PS: 이상 의 테스트 결 과 는 문자열 의 조작 장면 에 만 유효 합 니 다. 바 이 너 리 파일 을 조작 했다 면 버퍼 가 있 는 바이트 흐름 Buffered OutputStream 을 사용 해 야 합 니 다.
6. 확장 지식: 내용 추가
상기 코드 는 파일 을 다시 쓸 것 입 니 다. 기 존 에 내용 을 추가 하려 면 기록 흐름 을 만 들 때 하 나 를 더 설정 해 야 합 니 다
append
. 의 매개 변 수 는 true
입 니 다. 예 를 들 어 우리 가 사용 하면 FileWriter
파일 의 추가 가 이 루어 지면 구현 코드 는 다음 과 같 습 니 다.public static void fileWriterMethod(String filepath, String content) throws IOException {
// append true =
try (FileWriter fileWriter = new FileWriter(filepath, true)) {
fileWriter.append(content);
}
}
하면, 만약, 만약... 또는
BufferedWriter
도 구축 해 야 한다 PrintWriter
유사 시 하나 더 설정 new FileWriter
의 매개 변 수 는 append
이 고 실현 코드 는 다음 과 같다.try (BufferedWriter bufferedWriter = new BufferedWriter(
new FileWriter(filepath, true))) {
bufferedWriter.write(content);
}
true
클래스 가 파일 의 추가 쓰기 방법 을 실현 하려 면 Files
방법 을 호출 할 때 write
인 자 를 하나 더 전달 해 야 합 니 다. 실현 코드 는 다음 과 같 습 니 다.Files.write(Paths.get(filepath), content.getBytes(), StandardOpenOption.APPEND);
7. 총화
본 고 는 6 가지 파일 을 쓰 는 방법 을 보 여 주 었 는데 이 6 가지 방법 은 모두 3 가지 로 나 뉜 다. 문자 흐름 쓰기, 바이트 흐름 쓰기 와
StandardOpenOption.APPEND
클래스 기록.그 중에서 조작 이 가장 편리 한 것 은 Files
류 이지 만 성능 이 그다지 좋 지 않다.성능 에 대한 요구 가 있 으 면 캐 시 영역 이 있 는 흐름 을 사용 하여 작업 을 수행 하 는 것 을 추천 합 니 다. 예 를 들 어 Files
또는 BufferedWriter
.기 록 된 내용 이 문자열 이 라면 사용 BufferedOutputStream
을 추천 하고, 기 록 된 내용 이 바 이 너 리 파일 이 라면 사용 BufferedWriter
을 추천 합 니 다.참고 & 감사
https://www.cnblogs.com/absfree/p/5415092.html
공중 번호 '자바 중국어 공동체' 에 주목 하여 더 많은 건어물 을 발견 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.