මට ජාවා භාවිතා කරමින් රේඛාව අනුව 5-6 GB පමණ විශාල පෙළ ගොනුවක් කියවීමට අවශ්යයි.
මට මෙය ඉක්මනින් කළ හැක්කේ කෙසේද?
මට ජාවා භාවිතා කරමින් රේඛාව අනුව 5-6 GB පමණ විශාල පෙළ ගොනුවක් කියවීමට අවශ්යයි.
මට මෙය ඉක්මනින් කළ හැක්කේ කෙසේද?
Answers:
පොදු රටාවක් භාවිතා කිරීම
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
}
අක්ෂර කේතන ක්රමයක් නොමැති යැයි ඔබ සිතන්නේ නම් ඔබට දත්ත වේගයෙන් කියවිය හැකිය. උදා: ASCII-7 නමුත් එය එතරම් වෙනසක් නොකරනු ඇත. දත්ත සමඟ ඔබ කරන දේ බොහෝ කාලයක් ගතවනු ඇතැයි සිතිය හැකිය.
සංස්කරණය කරන්න: line
කාන්දු වීමේ විෂය පථය වළක්වන භාවිතා කිරීමට අඩු පොදු රටාවක් .
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
for(String line; (line = br.readLine()) != null; ) {
// process the line.
}
// line is not visible here.
}
යාවත්කාලීන කිරීම: ජාවා 8 හි ඔබට කළ හැකිය
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
සටහන: #close ක්රමය ඒ සඳහා කැඳවීම සහතික කිරීම සඳහා ඔබ උත්සාහය -සම්පත්-සම්පත් කොටසක තැබිය යුතුය, එසේ නොමැතිනම් GC බොහෝ කලකට පසුව එය සිදු කරන තුරු යටින් පවතින ගොනු හසුරුව කිසි විටෙකත් වසා නැත.
for(String line = br.readLine(); line != null; line = br.readLine())
Btw, ජාවා 8 හි ඔබට කළ හැක්කේ try( Stream<String> lines = Files.lines(...) ){ for( String line : (Iterable<String>) lines::iterator ) { ... } }
වෛර නොකිරීමට අපහසුය.
මෙම බ්ලොගය දෙස බලන්න:
බෆරයේ ප්රමාණය නියම කළ හැකිය, නැතහොත් පෙරනිමි ප්රමාණය භාවිතා කළ හැකිය. පෙරනිමිය බොහෝ අරමුණු සඳහා ප්රමාණවත් තරම් විශාලය.
// Open the file
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
fstream.close();
DataInputStream
අතර වැරදි ධාරාව වසා ඇත. ජාවා නිබන්ධනයේ කිසිදු වරදක් නොමැති අතර අත්තනෝමතික තෙවන පාර්ශවීය අන්තර්ජාල කුණු මේ ආකාරයෙන් සඳහන් කිරීම අවශ්ය නොවේ.
ජාවා 8 අවසන් වූ පසු (2014 මාර්තු) ඔබට ධාරාවන් භාවිතා කළ හැකිය:
try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
lines.forEachOrdered(line -> process(line));
}
ගොනුවේ සියලුම පේළි මුද්රණය කිරීම:
try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {
lines.forEachOrdered(System.out::println);
}
StandardCharsets.UTF_8
, භාවිතා කරන්න , Stream<String>
සහ භාවිතා කිරීමෙන් වළකින්න forEach()
සහ විශේෂයෙන් forEachOrdered()
හේතුවක් නොමැති නම්.
forEach(this::process)
, නමුත් ඔබ ඇතුළත ලැම්බඩා ලෙස කේත කොටස් ලිවුවහොත් එය කැත forEach()
වේ.
forEachOrdered
පිළිවෙලට ක්රියාත්මක කිරීමට අවශ්යයි . ගොනුවට පේළි දහස් ගණනක් ඇත්නම් මිස සමාන්තරකරණය සක්රිය නොවන බව මට පෙනී ගියද, එම අවස්ථාවේ දී ඔබට ධාරාව සමාන්තරගත කිරීමට නොහැකි වනු ඇති බව මතක තබා ගන්න.
පූර්ව ජාවා 7 සඳහා සම්පූර්ණ දෝෂ හැසිරවීම සහ සහාය අක්ෂර පිරිවිතරයන් සහිත නියැදියක් මෙන්න. ජාවා 7 සමඟ ඔබට උත්සාහ කරන්න-සම්පත්-සින්ටැක්ස් භාවිතා කළ හැකිය, එමඟින් කේතය පිරිසිදු කරයි.
ඔබට පෙරනිමි අක්ෂර කට්ටලය අවශ්ය නම් ඔබට ආදාන ප්රවාහය මඟ හැර FileReader භාවිතා කළ හැකිය.
InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
BufferedReader br = null; // buffered for readLine()
try {
String s;
ins = new FileInputStream("textfile.txt");
r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default
br = new BufferedReader(r);
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}
catch (Exception e)
{
System.err.println(e.getMessage()); // handle exception
}
finally {
if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }
}
සම්පූර්ණ දෝෂ හැසිරවීම සහිත Groovy අනුවාදය මෙන්න:
File f = new File("textfile.txt");
f.withReader("UTF-8") { br ->
br.eachLine { line ->
println line;
}
}
ByteArrayInputStream
විශාල පෙළ ගොනුව කියවීමේ සමඟ ඔබට ඇති ප්රායෝගික වැලක් පෝෂණය?
ජාවා 8 හි ඔබට කළ හැක්කේ:
try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))
{
for (String line : (Iterable<String>) lines::iterator)
{
;
}
}
සමහර සටහන්: ආපසු හරවන ලද ධාරාව Files.lines
(බොහෝ ධාරාවන් මෙන් නොව) වසා දැමිය යුතුය. මෙහි සඳහන් කර ඇති හේතු නිසා මම භාවිතා කිරීමෙන් වැළකී සිටිමි forEach()
. අමුතු කේතය (Iterable<String>) lines::iterator
නැවත ගලා යා හැකි ධාරාවකට යොමු කරයි.
Iterable
මෙම කේතය ක්රියාත්මක නොකිරීමෙන් ප්රයෝජනවත් වුවද නිශ්චිතවම කැතයි . වැඩ කිරීමට එයට වාත්තු (එනම් (Iterable<String>)
) අවශ්ය වේ.
for(String line : (Iterable<String>) lines.skip(1)::iterator)
Stream
විශේෂාංග, භාවිතා Files.newBufferedReader
වෙනුවට Files.lines
නැවත නැවතත් ඉල්ලා readLine()
තෙක් null
වැනි නිර්මාණය කරන භාවිතා කරනු වෙනුවට (Iterable<String>) lines::iterator
බොහෝ සරල බව පෙනේ ...
ඔබට කළ හැක්කේ ස්කෑනරය භාවිතයෙන් සම්පූර්ණ පා sc ය පරිලෝකනය කර පෙළ රේඛාව ඔස්සේ ගමන් කිරීමයි. ඇත්ත වශයෙන්ම ඔබ පහත සඳහන් දෑ ආනයනය කළ යුතුය:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public static void readText throws FileNotFoundException {
Scanner scan = new Scanner(new File("samplefilename.txt"));
while(scan.hasNextLine()){
String line = scan.nextLine();
//Here you can manipulate the string the way you want
}
}
ස්කෑනරය මූලික වශයෙන් සියලුම පෙළ පරිලෝකනය කරයි. මුළු ලූපය හරහා ගමන් කිරීම සඳහා කාල පුඩුවක් භාවිතා කරයි.
මෙම .hasNextLine()
කාර්යය තවමත් පෙළ තවත් පේලි තිබේ නම්, සැබෑ ආපසු හරවා යවන වීජ වේ. මෙම .nextLine()
ක්රියාව මඟින් ඔබට ඔබ ඔබට අවශ්ය ආකාරයට භාවිතා කළ හැකි වන සංගීත ලෙස සමස්ත මාර්ගය ලබා දෙයි. System.out.println(line)
පෙළ මුද්රණය කිරීමට උත්සාහ කරන්න .
පැති සටහන: .txt යනු ගොනු වර්ගයේ පෙළයි.
BufferedReader.readLine()
වන අතර ඔහු හොඳම ක්රියාකාරී ක්රමය ඉල්ලා සිටියේය.
මම ජාවා හි ගොනුවක් කියවීමට විවිධ ක්රම 10 ක් ලේඛනගත කර පරීක්ෂා කළ අතර ඒවා 1KB සිට 1GB දක්වා පරීක්ෂණ ලිපිගොනු කියවීමට සලස්වා ඒවා එකිනෙකට එරෙහිව ධාවනය කළෙමි . 1GB පරීක්ෂණ ගොනුවක් කියවීම සඳහා වේගවත්ම 3 ගොනු කියවීමේ ක්රම මෙන්න.
කාර්ය සාධන පරීක්ෂණ ක්රියාත්මක කිරීමේදී මම කොන්සෝලය වෙත කිසිවක් ප්රතිදානය නොකළ බැවින් එය පරීක්ෂණය මන්දගාමී වනු ඇති බව සලකන්න. අමු කියවීමේ වේගය පරීක්ෂා කිරීමට මට අවශ්ය විය.
1) java.nio.file.Files.readAllBytes ()
ජාවා 7, 8, 9 හි පරීක්ෂා කර ඇත. මෙය සමස්තයක් වශයෙන් වේගවත්ම ක්රමයයි. 1GB ගොනුවක් කියවීම නිරතුරුවම තත්පර 1 ට අඩු විය.
import java.io..File;
import java.io.IOException;
import java.nio.file.Files;
public class ReadFile_Files_ReadAllBytes {
public static void main(String [] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
byte [] fileBytes = Files.readAllBytes(file.toPath());
char singleChar;
for(byte b : fileBytes) {
singleChar = (char) b;
System.out.print(singleChar);
}
}
}
2) java.nio.file.Files.lines ()
මෙය ජාවා 8 සහ 9 හි සාර්ථකව අත්හදා බැලූ නමුත් ලැම්බඩා ප්රකාශන සඳහා සහය නොලැබීම නිසා එය ජාවා 7 හි ක්රියා නොකරනු ඇත. 1GB ගොනුවක කියවීමට තත්පර 3.5 ක් පමණ ගත වූ අතර එය විශාල ලිපිගොනු කියවීම තරම් දෙවන ස්ථානයට පත්විය.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
3) බෆර්ඩ් රීඩර්
ජාවා 7, 8, 9 හි වැඩ කිරීමට පරීක්ෂා කර ඇත. මෙය 1GB පරීක්ෂණ ගොනුවකින් කියවීමට තත්පර 4.5 ක් පමණ ගත විය.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
ඔබ සියලු 10 ගොනුව කියවීම ක්රම සඳහා සම්පූර්ණ ශ්රේණිගත සොයා ගත හැකි මෙහි .
System.out.print/println()
කරන්නේ මෙහි ය; ඔබගේ පළමු අවස්ථා දෙකේදී ගොනුව මතකයට ගැලපෙනු ඇතැයි ඔබ උපකල්පනය කරයි.
FileReader ඔබට කේතීකරණය නියම කිරීමට ඉඩ නොදේ, ඔබට එය නියම කිරීමට InputStreamReader
අවශ්ය නම් ඒ වෙනුවට භාවිතා කරන්න:
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
ඔබ මෙම ගොනුව වින්ඩෝස් වෙතින් ආනයනය කළේ නම්, එයට ANSI කේතීකරණ (Cp1252) තිබිය හැක, එබැවින් ඔබට කේතන ක්රමය නියම කළ යුතුය.
ජාවා 7 හි:
String folderPath = "C:/folderOfMyFile";
Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(path , charset)) {
while ((line = reader.readLine()) != null ) {
//separate all csv fields into string array
String[] lineVariables = line.split(",");
}
} catch (IOException e) {
System.err.println(e);
}
StandardCharsets.UTF_8
පරීක්ෂා කළ ව්යතිරේකය වළක්වා ගැනීමට භාවිතා කරන්නCharset.forName("UTF-8")
ජාවා 8 හි භාවිතා කිරීමට විකල්පයක් ද ඇත Files.lines()
. ඔබේ ආදාන ප්රභවය ගොනුවක් නොව a Reader
හෝ an වැනි වියුක්ත යමක් නම් InputStream
, ඔබට s හරහා රේඛා ප්රවාහනය කළ හැකියBufferedReader
lines()
ක්රමය.
උදාහරණයක් වශයෙන්:
try (BufferedReader reader = new BufferedReader(...)) {
reader.lines().forEach(line -> processLine(line));
}
processLine()
කියවන සෑම ආදාන රේඛාවක් සඳහාම කැඳවනු ඇත BufferedReader
.
සඳහා ගොනු කියවීම ජාවා සමග 8
package com.java.java8;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* The Class ReadLargeFile.
*
* @author Ankit Sood Apr 20, 2017
*/
public class ReadLargeFile {
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
try {
Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));
stream.forEach(System.out::println);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ඔබට ස්කෑනර් පන්තිය භාවිතා කළ හැකිය
Scanner sc=new Scanner(file);
sc.nextLine();
Scanner
කිරීම හොඳයි, නමුත් මෙම පිළිතුරට එය නිසි ලෙස භාවිතා කිරීම සඳහා සම්පූර්ණ කේතය ඇතුළත් නොවේ.
BufferedReader.readLine()
නිසැකවම කිහිප ගුණයකින් වේගවත් වුවද. ඔබ වෙනත් ආකාරයකින් සිතන්නේ නම් කරුණාකර ඔබේ හේතු ඉදිරිපත් කරන්න.
ඔබ තුළ readLine()
ක්රමය භාවිතා කළ class BufferedReader
යුතුය. එම පන්තියෙන් නව වස්තුවක් සාදා ඔහු මත මෙම ක්රමය ක්රියාත්මක කර එය නූලකට සුරකින්න.
මෙය සාක්ෂාත් කර ගැනීමට පැහැදිලි මාර්ගය,
උදාහරණයක් වශයෙන්:
තිබේ නම්, ඔබ dataFile.txt
ඔබේ වත්මන් බහලුම මත
import java.io.*;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class readByLine
{
public readByLine() throws FileNotFoundException
{
Scanner linReader = new Scanner(new File("dataFile.txt"));
while (linReader.hasNext())
{
String line = linReader.nextLine();
System.out.println(line);
}
linReader.close();
}
public static void main(String args[]) throws FileNotFoundException
{
new readByLine();
}
}
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
System.getProperty("os.name").equals("Linux")
==
!
BufferedReader br;
FileInputStream fin;
try {
fin = new FileInputStream(fileName);
br = new BufferedReader(new InputStreamReader(fin));
/*Path pathToFile = Paths.get(fileName);
br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/
String line = br.readLine();
while (line != null) {
String[] attributes = line.split(",");
Movie movie = createMovie(attributes);
movies.add(movie);
line = br.readLine();
}
fin.close();
br.close();
} catch (FileNotFoundException e) {
System.out.println("Your Message");
} catch (IOException e) {
System.out.println("Your Message");
}
එය මට වැඩ කරයි. එය ඔබටත් උපකාරී වනු ඇතැයි බලාපොරොත්තු වෙමු.
එය වඩාත් නිවැරදිව කිරීමට ඔබට ධාරාවන් භාවිතා කළ හැකිය:
Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);
මම සාමාන්යයෙන් කියවීමේ පුරුද්ද කෙළින්ම කරමි:
void readResource(InputStream source) throws IOException {
BufferedReader stream = null;
try {
stream = new BufferedReader(new InputStreamReader(source));
while (true) {
String line = stream.readLine();
if(line == null) {
break;
}
//process line
System.out.println(line)
}
} finally {
closeQuiet(stream);
}
}
static void closeQuiet(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignore) {
}
}
}
ඔබට මෙම කේතය භාවිතා කළ හැකිය:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadTextFile {
public static void main(String[] args) throws IOException {
try {
File f = new File("src/com/data.txt");
BufferedReader b = new BufferedReader(new FileReader(f));
String readLine = "";
System.out.println("Reading file using Buffered Reader");
while ((readLine = b.readLine()) != null) {
System.out.println(readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Org.apache.commons.io පැකේජය භාවිතා කිරීමෙන් , එය වැඩි කාර්ය සාධනයක් ලබා දුන්නේය, විශේෂයෙන් ජාවා 6 සහ ඊට පහළ භාවිතා කරන පැරණි කේත වල.
අඩු ව්යතිරේක හැසිරවීම් සහ වඩා ප්රයෝජනවත් ක්රම සහිත වඩා හොඳ API එකක් ජාවා 7 සතුව ඇත:
LineIterator lineIterator = null;
try {
lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
while (lineIterator.hasNext()) {
String currentLine = lineIterator.next();
// Some operation
}
}
finally {
LineIterator.closeQuietly(lineIterator);
}
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
ඔබට Apache Commons IO ද භාවිතා කළ හැකිය :
File file = new File("/home/user/file.txt");
try {
List<String> lines = FileUtils.readLines(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileUtils.readLines(file)
අතහැර දැමූ ක්රමයකි. මීට අමතරව, මෙම ක්රමය IOUtils.readLines
මඟින් බෆර්ඩ් රීඩර් සහ අරා ලැයිස්තු භාවිතා කරයි. මෙය රේඛීයව රේඛීය ක්රමයක් නොවන අතර නිසැකවම GB කිහිපයක් කියවීම සඳහා ප්රායෝගික එකක් නොවේ.