Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用ByteStream将1Mb文件读入字符串_Java_Guava_Readfile - Fatal编程技术网

Java 如何使用ByteStream将1Mb文件读入字符串

Java 如何使用ByteStream将1Mb文件读入字符串,java,guava,readfile,Java,Guava,Readfile,我现在使用的是FileInputStream int length = 1024*1024; FileInputStream fs = new FileInputStream(new File("foo")); fs.skip(offset); byte[] buf = new byte[length]; int bufferSize = fs.read(buf, 0, length); String s = new String(buf, 0, bufferSize); 我想知道如何使用gu

我现在使用的是FileInputStream

int length = 1024*1024;
FileInputStream fs = new FileInputStream(new File("foo"));
fs.skip(offset);
byte[] buf = new byte[length];
int bufferSize = fs.read(buf, 0, length);
String s = new String(buf, 0, bufferSize);
我想知道如何使用guava库中的ByTestStreams实现相同的结果


非常感谢

我不知道有什么更优雅的解决方案:

public static void main(String[] args) throws IOException {
    final int offset = 20;
    StringBuilder to = new StringBuilder();

    CharStreams.copy(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
        @Override
        public InputStream getInput() throws IOException {
            FileInputStream fs = new FileInputStream(new File("pom.xml"));

            ByteStreams.skipFully(fs, offset);

            return fs;
        }
    }, Charset.defaultCharset()), to);

    System.out.println(to);
}
publicstaticvoidmain(字符串[]args)引发IOException{
最终整数偏移=20;
StringBuilder to=新建StringBuilder();
CharStreams.copy(CharStreams.newReaderSupplier(newinputsupplier)(){
@凌驾
公共InputStream getInput()引发IOException{
FileInputStream fs=newfileinputstream(新文件(“pom.xml”);
熟练地(fs,偏移量);
返回fs;
}
},Charset.defaultCharset()),到);
系统输出打印项次(至);
}

唯一的优点是,当
字符串非常大时,可以通过避免转换为
字符串
来节省一些GC时间。我不知道有什么更优雅的解决方案:

public static void main(String[] args) throws IOException {
    final int offset = 20;
    StringBuilder to = new StringBuilder();

    CharStreams.copy(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
        @Override
        public InputStream getInput() throws IOException {
            FileInputStream fs = new FileInputStream(new File("pom.xml"));

            ByteStreams.skipFully(fs, offset);

            return fs;
        }
    }, Charset.defaultCharset()), to);

    System.out.println(to);
}
publicstaticvoidmain(字符串[]args)引发IOException{
最终整数偏移=20;
StringBuilder to=新建StringBuilder();
CharStreams.copy(CharStreams.newReaderSupplier(newinputsupplier)(){
@凌驾
公共InputStream getInput()引发IOException{
FileInputStream fs=newfileinputstream(新文件(“pom.xml”);
熟练地(fs,偏移量);
返回fs;
}
},Charset.defaultCharset()),到);
系统输出打印项次(至);
}

唯一的优点是,当
字符串非常大时,您可以通过避免转换为
字符串
来节省一些GC时间,为什么在不需要的时候尝试使用番石榴呢

在本例中,看起来您正在查找一个RandomAccessFile

File file = new File("foo");
long offset = ... ;
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
  byte[] buffer = new byte[1014*1024];
  raf.seek(offset);
  raf.readFully(buffer);
  return new String(buffer, Charset.defaultCharset());
}

没有必要的时候为什么还要用番石榴呢

在本例中,看起来您正在查找一个RandomAccessFile

File file = new File("foo");
long offset = ... ;
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
  byte[] buffer = new byte[1014*1024];
  raf.seek(offset);
  raf.readFully(buffer);
  return new String(buffer, Charset.defaultCharset());
}

下面是你如何用番石榴做的:

byte[] bytes = Files.asByteSource(new File("foo"))
    .slice(offset, length)
    .read();
String s = new String(bytes, Charsets.US_ASCII);
您的代码有几个问题(尽管它可能对文件很好,但对任何类型的流都不一定有效):

这不一定会跳过所有
偏移量
字节。您必须在返回值中检查它跳过的字节数,直到跳过了全部字节数,或者使用一些可以为您做到这一点的方法,例如
ByteStreams.skipFully

int bufferSize = fs.read(buf, 0, length);
同样,它不一定会读取所有
长度
字节,而且它读取的字节数可以是任意数量——一般来说,您不能依赖它

String s = new String(buf, 0, bufferSize);
这隐式地使用了系统默认的
字符集
,这通常不是一个好主意——当您确实需要它时,最好使用
Charset.defaultCharset()
将其显式化


还请注意,一般情况下,根据所使用的
字符集
(即,如果是ASCII,则可以,如果是Unicode,则不需要太多),一定数量的字节可能无法转换为合法的字符序列。

以下是使用番石榴的方法:

byte[] bytes = Files.asByteSource(new File("foo"))
    .slice(offset, length)
    .read();
String s = new String(bytes, Charsets.US_ASCII);
您的代码有几个问题(尽管它可能对文件很好,但对任何类型的流都不一定有效):

这不一定会跳过所有
偏移量
字节。您必须在返回值中检查它跳过的字节数,直到跳过了全部字节数,或者使用一些可以为您做到这一点的方法,例如
ByteStreams.skipFully

int bufferSize = fs.read(buf, 0, length);
同样,它不一定会读取所有
长度
字节,而且它读取的字节数可以是任意数量——一般来说,您不能依赖它

String s = new String(buf, 0, bufferSize);
这隐式地使用了系统默认的
字符集
,这通常不是一个好主意——当您确实需要它时,最好使用
Charset.defaultCharset()
将其显式化


还请注意,通常情况下,根据所使用的
字符集
(即,如果是ASCII,则可以,如果是Unicode,则不需要太多),一定数量的字节可能无法转换为合法的字符序列。我指的是长度。我只是修改了我的代码,老实说,你现在用的方式可能比用番石榴做的要短。
ByteStreams
api实际上只有读取所有字节的方法,而不是从某个偏移量开始的字节。您可以读取所有字节,并且只使用
偏移量
长度
,但是从切换到番石榴中您并没有真正获得任何好处。哎呀,对不起。我指的是长度。我只是修改了我的代码,老实说,你现在用的方式可能比用番石榴做的要短。
ByteStreams
api实际上只有读取所有字节的方法,而不是从某个偏移量开始的字节。您可以读取所有字节,并且只使用
偏移量
长度
,但是切换到番石榴并没有真正获得任何好处。